SECURITY: update.php: Remove eval-stdin.php if necessary
authorKunal Mehta <legoktm@member.fsf.org>
Sat, 11 Nov 2017 00:53:24 +0000 (16:53 -0800)
committerReedy <reedy@wikimedia.org>
Wed, 15 Nov 2017 02:56:15 +0000 (02:56 +0000)
If phpunit's eval-stdin.php file exists and is one of the vulnerable
versions, delete it when running update.php as most people should run
that when updating to a new release. If the unlink() call fails, we'll
warn the user but continue with update.php processing and hope they've
mitigated it in some other way.

Bug: T180231
Change-Id: I5b838686ede9764083c52853cc05c52ea72739df

maintenance/update.php

index ba66c76..70cea51 100755 (executable)
@@ -170,6 +170,24 @@ class UpdateMediaWiki extends Maintenance {
 
                $time1 = microtime( true );
 
+               $badPhpUnit = dirname( __DIR__ ) . '/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php';
+               if ( file_exists( $badPhpUnit ) ) {
+                       // Bad versions of the file are:
+                       // https://raw.githubusercontent.com/sebastianbergmann/phpunit/c820f915bfae34e5a836f94967a2a5ea5ef34f21/src/Util/PHP/eval-stdin.php
+                       // https://raw.githubusercontent.com/sebastianbergmann/phpunit/3aaddb1c5bd9b9b8d070b4cf120e71c36fd08412/src/Util/PHP/eval-stdin.php
+                       $md5 = md5_file( $badPhpUnit );
+                       if ( $md5 === '120ac49800671dc383b6f3709c25c099'
+                               || $md5 === '28af792cb38fc9a1b236b91c1aad2876'
+                       ) {
+                               $success = unlink( $badPhpUnit );
+                               if ( $success ) {
+                                       $this->output( "Removed PHPUnit eval-stdin.php to protect against CVE-2017-9841\n" );
+                               } else {
+                                       $this->error( "Unable to remove $badPhpUnit, you should manually. See CVE-2017-9841" );
+                               }
+                       }
+               }
+
                $shared = $this->hasOption( 'doshared' );
 
                $updates = [ 'core', 'extensions' ];