]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - includes/libs/IEUrlExtension.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / libs / IEUrlExtension.php
index 100454d45021d376ea9c0d524aec56b4434e43e7..2d1c58b66a3c07d888040b49de2056f3842b9d47 100644 (file)
@@ -1,31 +1,51 @@
 <?php
+/**
+ * Checks for validity of requested URL's extension.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
 
 /**
- * Internet Explorer derives a cache filename from a URL, and then in certain 
- * circumstances, uses the extension of the resulting file to determine the 
- * content type of the data, ignoring the Content-Type header. 
+ * Internet Explorer derives a cache filename from a URL, and then in certain
+ * circumstances, uses the extension of the resulting file to determine the
+ * content type of the data, ignoring the Content-Type header.
  *
  * This can be a problem, especially when non-HTML content is sent by MediaWiki,
  * and Internet Explorer interprets it as HTML, exposing an XSS vulnerability.
  *
- * Usually the script filename (e.g. api.php) is present in the URL, and this 
+ * Usually the script filename (e.g. api.php) is present in the URL, and this
  * makes Internet Explorer think the extension is a harmless script extension.
- * But Internet Explorer 6 and earlier allows the script extension to be 
- * obscured by encoding the dot as "%2E". 
+ * But Internet Explorer 6 and earlier allows the script extension to be
+ * obscured by encoding the dot as "%2E".
  *
- * This class contains functions which help in detecting and dealing with this 
+ * This class contains functions which help in detecting and dealing with this
  * situation.
  *
- * Checking the URL for a bad extension is somewhat complicated due to the fact 
+ * Checking the URL for a bad extension is somewhat complicated due to the fact
  * that CGI doesn't provide a standard method to determine the URL. Instead it
- * is necessary to pass a subset of $_SERVER variables, which we then attempt 
+ * is necessary to pass a subset of $_SERVER variables, which we then attempt
  * to use to guess parts of the URL.
  */
 class IEUrlExtension {
        /**
         * Check a subset of $_SERVER (or the whole of $_SERVER if you like)
-        * to see if it indicates that the request was sent with a bad file 
-        * extension. Returns true if the request should be denied or modified, 
+        * to see if it indicates that the request was sent with a bad file
+        * extension. Returns true if the request should be denied or modified,
         * false otherwise. The relevant $_SERVER elements are:
         *
         *   - SERVER_SOFTWARE
@@ -35,15 +55,16 @@ class IEUrlExtension {
         *
         * If the a variable is unset in $_SERVER, it should be unset in $vars.
         *
-        * @param $vars A subset of $_SERVER.
-        * @param $extWhitelist Extensions which are allowed, assumed harmless.
+        * @param array $vars A subset of $_SERVER.
+        * @param array $extWhitelist Extensions which are allowed, assumed harmless.
+        * @return bool
         */
-       public static function areServerVarsBad( $vars, $extWhitelist = array() ) {
+       public static function areServerVarsBad( $vars, $extWhitelist = [] ) {
                // Check QUERY_STRING or REQUEST_URI
                if ( isset( $vars['SERVER_SOFTWARE'] )
                        && isset( $vars['REQUEST_URI'] )
-                       && self::haveUndecodedRequestUri( $vars['SERVER_SOFTWARE'] ) )
-               {
+                       && self::haveUndecodedRequestUri( $vars['SERVER_SOFTWARE'] )
+               {
                        $urlPart = $vars['REQUEST_URI'];
                } elseif ( isset( $vars['QUERY_STRING'] ) ) {
                        $urlPart = $vars['QUERY_STRING'];
@@ -55,11 +76,11 @@ class IEUrlExtension {
                        return true;
                }
 
-               // Some servers have PATH_INFO but not REQUEST_URI, so we check both 
+               // Some servers have PATH_INFO but not REQUEST_URI, so we check both
                // to be on the safe side.
                if ( isset( $vars['PATH_INFO'] )
-                       && self::isUrlExtensionBad( $vars['PATH_INFO'], $extWhitelist ) )
-               {
+                       && self::isUrlExtensionBad( $vars['PATH_INFO'], $extWhitelist )
+               {
                        return true;
                }
 
@@ -71,12 +92,12 @@ class IEUrlExtension {
         * Given a right-hand portion of a URL, determine whether IE would detect
         * a potentially harmful file extension.
         *
-        * @param $urlPart The right-hand portion of a URL
-        * @param $extWhitelist An array of file extensions which may occur in this
+        * @param string $urlPart The right-hand portion of a URL
+        * @param array $extWhitelist An array of file extensions which may occur in this
         *    URL, and which should be allowed.
         * @return bool
         */
-       public static function isUrlExtensionBad( $urlPart, $extWhitelist = array() ) {
+       public static function isUrlExtensionBad( $urlPart, $extWhitelist = [] ) {
                if ( strval( $urlPart ) === '' ) {
                        return false;
                }
@@ -87,7 +108,7 @@ class IEUrlExtension {
                        return false;
                }
 
-               if ( in_array( $extension, array( 'php', 'php5' ) ) ) {
+               if ( in_array( $extension, [ 'php', 'php5' ] ) ) {
                        // Script extension, OK
                        return false;
                }
@@ -97,10 +118,9 @@ class IEUrlExtension {
                }
 
                if ( !preg_match( '/^[a-zA-Z0-9_-]+$/', $extension ) ) {
-                       // Non-alphanumeric extension, unlikely to be registered. 
-                       //
+                       // Non-alphanumeric extension, unlikely to be registered.
                        // The regex above is known to match all registered file extensions
-                       // in a default Windows XP installation. It's important to allow 
+                       // in a default Windows XP installation. It's important to allow
                        // extensions with ampersands and percent signs, since that reduces
                        // the number of false positives substantially.
                        return false;
@@ -111,10 +131,13 @@ class IEUrlExtension {
        }
 
        /**
-        * Returns a variant of $url which will pass isUrlExtensionBad() but has the 
+        * Returns a variant of $url which will pass isUrlExtensionBad() but has the
         * same GET parameters, or false if it can't figure one out.
+        * @param string $url
+        * @param array $extWhitelist
+        * @return bool|string
         */
-       public static function fixUrlForIE6( $url, $extWhitelist = array() ) {
+       public static function fixUrlForIE6( $url, $extWhitelist = [] ) {
                $questionPos = strpos( $url, '?' );
                if ( $questionPos === false ) {
                        $beforeQuery = $url . '?';
@@ -127,7 +150,7 @@ class IEUrlExtension {
                        $query = substr( $url, $questionPos + 1 );
                }
 
-               // Multiple question marks cause problems. Encode the second and 
+               // Multiple question marks cause problems. Encode the second and
                // subsequent question mark.
                $query = str_replace( '?', '%3E', $query );
                // Append an invalid path character so that IE6 won't see the end of the
@@ -153,17 +176,17 @@ class IEUrlExtension {
         * insecure.
         *
         * The criteria for finding an extension are as follows:
-        * - a possible extension is a dot followed by one or more characters not 
+        * - a possible extension is a dot followed by one or more characters not
         *   in <>\"/:|?.#
-        * - if we find a possible extension followed by the end of the string or 
+        * - if we find a possible extension followed by the end of the string or
         *   a #, that's our extension
         * - if we find a possible extension followed by a ?, that's our extension
-        *    - UNLESS it's exe, dll or cgi, in which case we ignore it and continue 
+        *    - UNLESS it's exe, dll or cgi, in which case we ignore it and continue
         *      searching for another possible extension
-        * - if we find a possible extension followed by a dot or another illegal 
+        * - if we find a possible extension followed by a dot or another illegal
         *   character, we ignore it and continue searching
-        * 
-        * @param $url string URL
+        *
+        * @param string $url URL
         * @return mixed Detected extension (string), or false if none found
         */
        public static function findIE6Extension( $url ) {
@@ -182,7 +205,7 @@ class IEUrlExtension {
                                // End of string, we're done
                                return false;
                        }
-                       
+
                        // We found a dot. Skip past it
                        $pos++;
                        $remainingLength = $urlLength - $pos;
@@ -200,15 +223,15 @@ class IEUrlExtension {
                                // If the extension is NOT exe, dll or cgi, return it
                                $extension = substr( $url, $pos, $nextPos - $pos );
                                if ( strcasecmp( $extension, 'exe' ) && strcasecmp( $extension, 'dll' ) &&
-                                       strcasecmp( $extension, 'cgi' ) )
-                               {
+                                       strcasecmp( $extension, 'cgi' )
+                               {
                                        return $extension;
                                }
                                // Else continue looking
                        }
                        // We found an illegal character or another dot
                        // Skip to that character and continue the loop
-                       $pos = $nextPos + 1;
+                       $pos = $nextPos;
                        $remainingLength = $urlLength - $pos;
                }
                return false;
@@ -220,23 +243,22 @@ class IEUrlExtension {
         * with %2E not decoded to ".". On such a server, it is possible to detect
         * whether the script filename has been obscured.
         *
-        * The function returns false if the server is not known to have this 
-        * behaviour. Microsoft IIS in particular is known to decode escaped script
+        * The function returns false if the server is not known to have this
+        * behavior. Microsoft IIS in particular is known to decode escaped script
         * filenames.
         *
         * SERVER_SOFTWARE typically contains either a plain string such as "Zeus",
-        * or a specification in the style of a User-Agent header, such as 
+        * or a specification in the style of a User-Agent header, such as
         * "Apache/1.3.34 (Unix) mod_ssl/2.8.25 OpenSSL/0.9.8a PHP/4.4.2"
         *
-        * @param $serverSoftware
+        * @param string $serverSoftware
         * @return bool
-        *
         */
        public static function haveUndecodedRequestUri( $serverSoftware ) {
-               static $whitelist = array(
-                       'Apache', 
-                       'Zeus', 
-                       'LiteSpeed' );
+               static $whitelist = [
+                       'Apache',
+                       'Zeus',
+                       'LiteSpeed' ];
                if ( preg_match( '/^(.*?)($|\/| )/', $serverSoftware, $m ) ) {
                        return in_array( $m[1], $whitelist );
                } else {