Index: trunk/phase3/CREDITS |
— | — | @@ -63,7 +63,6 @@ |
64 | 64 | * Brent G |
65 | 65 | * Brianna Laugher |
66 | 66 | * Carlin |
67 | | -* Chris Wrinn |
68 | 67 | * church of emacs |
69 | 68 | * Dan Nessett |
70 | 69 | * Daniel Arnold |
Index: trunk/phase3/includes/WebRequest.php |
— | — | @@ -670,6 +670,33 @@ |
671 | 671 | public function setSessionData( $key, $data ) { |
672 | 672 | $_SESSION[$key] = $data; |
673 | 673 | } |
| 674 | + |
| 675 | + /** |
| 676 | + * Returns true if the PATH_INFO ends with an extension other than a script |
| 677 | + * extension. This could confuse IE for scripts that send arbitrary data which |
| 678 | + * is not HTML but may be detected as such. |
| 679 | + * |
| 680 | + * Various past attempts to use the URL to make this check have generally |
| 681 | + * run up against the fact that CGI does not provide a standard method to |
| 682 | + * determine the URL. PATH_INFO may be mangled (e.g. if cgi.fix_pathinfo=0), |
| 683 | + * but only by prefixing it with the script name and maybe some other stuff, |
| 684 | + * the extension is not mangled. So this should be a reasonably portable |
| 685 | + * way to perform this security check. |
| 686 | + */ |
| 687 | + public function isPathInfoBad() { |
| 688 | + global $wgScriptExtension; |
| 689 | + |
| 690 | + if ( !isset( $_SERVER['PATH_INFO'] ) ) { |
| 691 | + return false; |
| 692 | + } |
| 693 | + $pi = $_SERVER['PATH_INFO']; |
| 694 | + $dotPos = strrpos( $pi, '.' ); |
| 695 | + if ( $dotPos === false ) { |
| 696 | + return false; |
| 697 | + } |
| 698 | + $ext = substr( $pi, $dotPos ); |
| 699 | + return !in_array( $ext, array( $wgScriptExtension, '.php', '.php5' ) ); |
| 700 | + } |
674 | 701 | } |
675 | 702 | |
676 | 703 | /** |
— | — | @@ -740,4 +767,8 @@ |
741 | 768 | $this->notImplemented( __METHOD__ ); |
742 | 769 | } |
743 | 770 | |
| 771 | + public function isPathInfoBad() { |
| 772 | + return false; |
| 773 | + } |
| 774 | + |
744 | 775 | } |
Index: trunk/phase3/includes/RawPage.php |
— | — | @@ -109,19 +109,9 @@ |
110 | 110 | } |
111 | 111 | |
112 | 112 | function view() { |
113 | | - global $wgOut, $wgScript; |
| 113 | + global $wgOut, $wgScript, $wgRequest; |
114 | 114 | |
115 | | - $url = wfGetScriptUrl(); |
116 | | - if( $url == '' ) { |
117 | | - # This will make the next check fail with a confusing error |
118 | | - # message, so we should mention it separately. |
119 | | - wfHttpError( 500, 'Internal Server Error', |
120 | | - "\$_SERVER['URL'] is not set. Perhaps you're using CGI" . |
121 | | - " and haven't set cgi.fix_pathinfo = 1 in php.ini?" ); |
122 | | - return; |
123 | | - } |
124 | | - |
125 | | - if( strcmp( $wgScript, $url ) ) { |
| 115 | + if( $wgRequest->isPathInfoBad() ) { |
126 | 116 | # Internet Explorer will ignore the Content-Type header if it |
127 | 117 | # thinks it sees a file extension it recognizes. Make sure that |
128 | 118 | # all raw requests are done through the script node, which will |
— | — | @@ -135,6 +125,7 @@ |
136 | 126 | # |
137 | 127 | # Just return a 403 Forbidden and get it over with. |
138 | 128 | wfHttpError( 403, 'Forbidden', |
| 129 | + 'Invalid file extension found in PATH_INFO. ' . |
139 | 130 | 'Raw pages must be accessed through the primary script entry point.' ); |
140 | 131 | return; |
141 | 132 | } |
Index: trunk/phase3/mwScriptLoader.php |
— | — | @@ -30,8 +30,9 @@ |
31 | 31 | wfProfileIn( 'mwScriptLoader.php' ); |
32 | 32 | |
33 | 33 | |
34 | | -if( strpos( wfGetScriptUrl(), "mwScriptLoader{$wgScriptExtension}" ) === false ){ |
| 34 | +if( $wgRequest->isPathInfoBad() ){ |
35 | 35 | wfHttpError( 403, 'Forbidden', |
| 36 | + 'Invalid file extension found in PATH_INFO. ' . |
36 | 37 | 'mwScriptLoader must be accessed through the primary script entry point.' ); |
37 | 38 | return; |
38 | 39 | } |
— | — | @@ -51,4 +52,4 @@ |
52 | 53 | $myScriptLoader = new jsScriptLoader(); |
53 | 54 | $myScriptLoader->doScriptLoader(); |
54 | 55 | |
55 | | -wfProfileOut( 'mwScriptLoader.php' ); |
\ No newline at end of file |
| 56 | +wfProfileOut( 'mwScriptLoader.php' ); |
Index: trunk/phase3/api.php |
— | — | @@ -49,16 +49,10 @@ |
50 | 50 | // which will end up triggering HTML detection and execution, hence |
51 | 51 | // XSS injection and all that entails. |
52 | 52 | // |
53 | | -// Ensure that all access is through the canonical entry point... |
54 | | -// |
55 | | -if( isset( $_SERVER['SCRIPT_NAME'] ) ) { |
56 | | - $url = $_SERVER['SCRIPT_NAME']; |
57 | | -} else { |
58 | | - $url = $_SERVER['URL']; |
59 | | -} |
60 | | -if( strcmp( "$wgScriptPath/api$wgScriptExtension", $url ) ) { |
| 53 | +if( $wgRequest->isPathInfoBad() ) { |
61 | 54 | wfHttpError( 403, 'Forbidden', |
62 | | - 'API must be accessed through the primary script entry point.' ); |
| 55 | + 'Invalid file extension found in PATH_INFO. ' . |
| 56 | + 'The API must be accessed through the primary script entry point.' ); |
63 | 57 | return; |
64 | 58 | } |
65 | 59 | |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -406,6 +406,8 @@ |
407 | 407 | * (bug 20273) Fix broken output when no pages are found in the content |
408 | 408 | namespaces |
409 | 409 | * (bug 20265) Make AncientPages and UnusedFiles work on SQLite |
| 410 | +* Fixed XSS vulnerability for Internet Explorer clients (only pre-release |
| 411 | + versions of MediaWiki were affected). |
410 | 412 | |
411 | 413 | == API changes in 1.16 == |
412 | 414 | |