SECURITY: Improve cross-domain-policy mangling
authorBrad Jorsch <bjorsch@wikimedia.org>
Mon, 18 Jan 2016 17:00:41 +0000 (12:00 -0500)
committerChad Horohoe <chadh@wikimedia.org>
Fri, 20 May 2016 16:48:11 +0000 (09:48 -0700)
Take into account that the tag might have parameters.

Bug: T123653
Change-Id: Ie9799f5ea45badfb4e7b4be7e7fbc1c35cc86f26

Signed-off-by: Chad Horohoe <chadh@wikimedia.org>
includes/OutputHandler.php
includes/api/ApiFormatJson.php
includes/api/ApiFormatPhp.php
tests/phpunit/includes/api/format/ApiFormatJsonTest.php

index c9c326b..2f47006 100644 (file)
@@ -154,8 +154,8 @@ function wfGzipHandler( $s ) {
  */
 function wfMangleFlashPolicy( $s ) {
        # Avoid weird excessive memory usage in PCRE on big articles
-       if ( preg_match( '/\<\s*cross-domain-policy\s*\>/i', $s ) ) {
-               return preg_replace( '/\<\s*cross-domain-policy\s*\>/i', '<NOT-cross-domain-policy>', $s );
+       if ( preg_match( '/\<\s*cross-domain-policy(?=\s|\>)/i', $s ) ) {
+               return preg_replace( '/\<(\s*)(cross-domain-policy(?=\s|\>))/i', '<$1NOT-$2', $s );
        } else {
                return $s;
        }
index 41de925..814450e 100644 (file)
@@ -103,9 +103,9 @@ class ApiFormatJson extends ApiFormatBase {
                // Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
                // Flash, but what it does isn't friendly for the API, so we need to
                // work around it.
-               if ( preg_match( '/\<\s*cross-domain-policy\s*\>/i', $json ) ) {
+               if ( preg_match( '/\<\s*cross-domain-policy(?=\s|\>)/i', $json ) ) {
                        $json = preg_replace(
-                               '/\<(\s*cross-domain-policy\s*)\>/i', '\\u003C$1\\u003E', $json
+                               '/\<(\s*cross-domain-policy(?=\s|\>))/i', '\\u003C$1', $json
                        );
                }
 
index d111af5..fc25f47 100644 (file)
@@ -65,7 +65,7 @@ class ApiFormatPhp extends ApiFormatBase {
                // just be broken in a useful manner.
                if ( $this->getConfig()->get( 'MangleFlashPolicy' ) &&
                        in_array( 'wfOutputHandler', ob_list_handlers(), true ) &&
-                       preg_match( '/\<\s*cross-domain-policy\s*\>/i', $text )
+                       preg_match( '/\<\s*cross-domain-policy(?=\s|\>)/i', $text )
                ) {
                        $this->dieUsage(
                                'This response cannot be represented using format=php. ' .
index 8437228..7eb2a35 100644 (file)
@@ -67,7 +67,7 @@ class ApiFormatJsonTest extends ApiFormatTestBase {
                                [ [ 1 ], '/**/myCallback([1])', [ 'callback' => 'myCallback' ] ],
 
                                // Cross-domain mangling
-                               [ [ '< Cross-Domain-Policy >' ], '["\u003C Cross-Domain-Policy \u003E"]' ],
+                               [ [ '< Cross-Domain-Policy >' ], '["\u003C Cross-Domain-Policy >"]' ],
                        ] ),
                        self::addFormatVersion( 2, [
                                // Basic types
@@ -121,7 +121,7 @@ class ApiFormatJsonTest extends ApiFormatTestBase {
                                [ [ 1 ], '/**/myCallback([1])', [ 'callback' => 'myCallback' ] ],
 
                                // Cross-domain mangling
-                               [ [ '< Cross-Domain-Policy >' ], '["\u003C Cross-Domain-Policy \u003E"]' ],
+                               [ [ '< Cross-Domain-Policy >' ], '["\u003C Cross-Domain-Policy >"]' ],
                        ] )
                );
        }