(bug 27094) fix path traversal vulnerability
authorTim Starling <tstarling@users.mediawiki.org>
Tue, 1 Feb 2011 22:43:58 +0000 (22:43 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Tue, 1 Feb 2011 22:43:58 +0000 (22:43 +0000)
includes/StubObject.php
languages/Language.php

index 391a9f1..96551f3 100644 (file)
@@ -152,7 +152,7 @@ class StubUserLang extends StubObject {
                $code = strtolower( $code );
 
                # Validate $code
-               if( empty( $code ) || !preg_match( '/^[a-z-]+$/', $code ) || ( $code === 'qqq' ) ) {
+               if( empty( $code ) || !Language::isValidCode( $code ) || ( $code === 'qqq' ) ) {
                        wfDebug( "Invalid user language code\n" );
                        $code = $wgLanguageCode;
                }
index 6cfee8f..edd607b 100644 (file)
@@ -154,6 +154,14 @@ class Language {
        protected static function newFromCode( $code ) {
                global $IP;
                static $recursionLevel = 0;
+
+               // Protect against path traversal below
+               if ( !Language::isValidCode( $code ) 
+                       || strcspn( $code, "/\\\000" ) !== strlen( $code ) ) 
+               {
+                       throw new MWException( "Invalid language code \"$code\"" );
+               }
+
                if ( $code == 'en' ) {
                        $class = 'Language';
                } else {
@@ -183,6 +191,14 @@ class Language {
                return $lang;
        }
 
+       /**
+        * Returns true if a language code string is of a valid form, whether or 
+        * not it exists.
+        */
+       public static function isValidCode( $code ) {
+               return (bool)preg_match( '/^[a-z-]+$/', $code );
+       }
+
        /**
         * Get the LocalisationCache instance
         */
@@ -2812,6 +2828,13 @@ class Language {
         * @return string $prefix . $mangledCode . $suffix
         */
        static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) {
+               // Protect against path traversal
+               if ( !Language::isValidCode( $code ) 
+                       || strcspn( $code, "/\\\000" ) !== strlen( $code ) ) 
+               {
+                       throw new MWException( "Invalid language code \"$code\"" );
+               }
+               
                return $prefix . str_replace( '-', '_', ucfirst( $code ) ) . $suffix;
        }