Remove support for magic_quotes_gpc
[lhc/web/wiklou.git] / includes / WebRequest.php
index ac8e159..4e5fb7a 100644 (file)
@@ -25,8 +25,8 @@
 
 /**
  * The WebRequest class encapsulates getting at data passed in the
- * URL or via a POSTed form, handling remove of "magic quotes" slashes,
- * stripping illegal input characters and normalizing Unicode sequences.
+ * URL or via a POSTed form stripping illegal input characters and
+ * normalizing Unicode sequences.
  *
  * Usually this is used via a global singleton, $wgRequest. You should
  * not create a second WebRequest object; make a FauxRequest object if
@@ -57,10 +57,9 @@ class WebRequest {
        protected $protocol;
 
        public function __construct() {
-               /// @todo FIXME: This preemptive de-quoting can interfere with other web libraries
-               ///        and increases our memory footprint. It would be cleaner to do on
-               ///        demand; but currently we have no wrapper for $_SERVER etc.
-               $this->checkMagicQuotes();
+               if ( function_exists( 'get_magic_quotes_gpc' ) && get_magic_quotes_gpc() ) {
+                       throw new MWException( "MediaWiki does not function when magic quotes are enabled." );
+               }
 
                // POST overrides GET data
                // We don't use $_REQUEST here to avoid interference from cookies...
@@ -271,51 +270,6 @@ class WebRequest {
                return array();
        }
 
-       /**
-        * Recursively strips slashes from the given array;
-        * used for undoing the evil that is magic_quotes_gpc.
-        *
-        * @param array $arr will be modified
-        * @param bool $topLevel Specifies if the array passed is from the top
-        * level of the source. In PHP5 magic_quotes only escapes the first level
-        * of keys that belong to an array.
-        * @return array The original array
-        * @see http://www.php.net/manual/en/function.get-magic-quotes-gpc.php#49612
-        */
-       private function &fix_magic_quotes( &$arr, $topLevel = true ) {
-               $clean = array();
-               foreach ( $arr as $key => $val ) {
-                       if ( is_array( $val ) ) {
-                               $cleanKey = $topLevel ? stripslashes( $key ) : $key;
-                               $clean[$cleanKey] = $this->fix_magic_quotes( $arr[$key], false );
-                       } else {
-                               $cleanKey = stripslashes( $key );
-                               $clean[$cleanKey] = stripslashes( $val );
-                       }
-               }
-               $arr = $clean;
-               return $arr;
-       }
-
-       /**
-        * If magic_quotes_gpc option is on, run the global arrays
-        * through fix_magic_quotes to strip out the stupid slashes.
-        * WARNING: This should only be done once! Running a second
-        * time could damage the values.
-        */
-       private function checkMagicQuotes() {
-               $mustFixQuotes = function_exists( 'get_magic_quotes_gpc' )
-                       && get_magic_quotes_gpc();
-               if ( $mustFixQuotes ) {
-                       $this->fix_magic_quotes( $_COOKIE );
-                       $this->fix_magic_quotes( $_ENV );
-                       $this->fix_magic_quotes( $_GET );
-                       $this->fix_magic_quotes( $_POST );
-                       $this->fix_magic_quotes( $_REQUEST );
-                       $this->fix_magic_quotes( $_SERVER );
-               }
-       }
-
        /**
         * Recursively normalizes UTF-8 strings in the given array.
         *
@@ -489,7 +443,7 @@ class WebRequest {
         * @param float $default
         * @return float
         */
-       public function getFloat( $name, $default = 0 ) {
+       public function getFloat( $name, $default = 0.0 ) {
                return floatval( $this->getVal( $name, $default ) );
        }
 
@@ -754,17 +708,6 @@ class WebRequest {
                return $this->appendQueryArray( wfCgiToArray( $query ) );
        }
 
-       /**
-        * HTML-safe version of appendQuery().
-        * @deprecated: Deprecated in 1.20, warnings in 1.21, remove in 1.22.
-        *
-        * @param string $query Query string fragment; do not include initial '?'
-        * @return string
-        */
-       public function escapeAppendQuery( $query ) {
-               return htmlspecialchars( $this->appendQuery( $query ) );
-       }
-
        /**
         * @param string $key
         * @param string $value
@@ -1119,40 +1062,45 @@ HTML;
 
                # collect the originating ips
                $ip = $this->getRawIP();
+               if ( !$ip ) {
+                       throw new MWException( 'Unable to determine IP.' );
+               }
 
                # Append XFF
                $forwardedFor = $this->getHeader( 'X-Forwarded-For' );
                if ( $forwardedFor !== false ) {
+                       $isConfigured = IP::isConfiguredProxy( $ip );
                        $ipchain = array_map( 'trim', explode( ',', $forwardedFor ) );
                        $ipchain = array_reverse( $ipchain );
-                       if ( $ip ) {
-                               array_unshift( $ipchain, $ip );
-                       }
+                       array_unshift( $ipchain, $ip );
 
                        # Step through XFF list and find the last address in the list which is a
                        # trusted server. Set $ip to the IP address given by that trusted server,
                        # unless the address is not sensible (e.g. private). However, prefer private
                        # IP addresses over proxy servers controlled by this site (more sensible).
+                       # Note that some XFF values might be "unknown" with Squid/Varnish.
                        foreach ( $ipchain as $i => $curIP ) {
-                               // ignore 'unknown' value from Squid when 'forwarded_for off' and try next
-                               if ( $curIP === 'unknown' ) {
-                                       continue;
-                               }
                                $curIP = IP::sanitizeIP( IP::canonicalize( $curIP ) );
-                               if ( wfIsTrustedProxy( $curIP ) && isset( $ipchain[$i + 1] ) ) {
-                                       if ( wfIsConfiguredProxy( $curIP ) || // bug 48919; treat IP as sane
-                                               IP::isPublic( $ipchain[$i + 1] ) ||
-                                               $wgUsePrivateIPs
-                                       ) {
-                                               $nextIP = IP::canonicalize( $ipchain[$i + 1] );
-                                               if ( !$nextIP && wfIsConfiguredProxy( $ip ) ) {
-                                                       // We have not yet made it past CDN/proxy servers of this site,
-                                                       // so either they are misconfigured or there is some IP spoofing.
-                                                       throw new MWException( "Invalid IP given in XFF '$forwardedFor'." );
-                                               }
-                                               $ip = $nextIP;
-                                               continue;
+                               if ( !$curIP || !isset( $ipchain[$i + 1] ) || $ipchain[$i + 1] === 'unknown'
+                                       || !IP::isTrustedProxy( $curIP )
+                               ) {
+                                       break; // IP is not valid/trusted or does not point to anything
+                               }
+                               if (
+                                       IP::isPublic( $ipchain[$i + 1] ) ||
+                                       $wgUsePrivateIPs ||
+                                       IP::isConfiguredProxy( $curIP ) // bug 48919; treat IP as sane
+                               ) {
+                                       // Follow the next IP according to the proxy
+                                       $nextIP = IP::canonicalize( $ipchain[$i + 1] );
+                                       if ( !$nextIP && $isConfigured ) {
+                                               // We have not yet made it past CDN/proxy servers of this site,
+                                               // so either they are misconfigured or there is some IP spoofing.
+                                               throw new MWException( "Invalid IP given in XFF '$forwardedFor'." );
                                        }
+                                       $ip = $nextIP;
+                                       // keep traversing the chain
+                                       continue;
                                }
                                break;
                        }