php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

Patch bug64646_php5_plus_test for Program Execution Bug #69646

Patch version 2015-05-18 14:48 UTC

Return to Bug #69646 | Download this patch
Patch Revisions:

Developer: ab@php.net

diff --git a/ext/standard/exec.c b/ext/standard/exec.c
index d6938a4..d0b1e01 100644
--- a/ext/standard/exec.c
+++ b/ext/standard/exec.c
@@ -380,6 +380,14 @@ PHPAPI char *php_escape_shell_arg(char *str)
 		}
 	}
 #ifdef PHP_WIN32
+	if (y > 0 && '\\' == cmd[y - 1]) {
+		int k = 0, n = y - 1;
+		for (; n >= 0 && '\\' == cmd[n]; n--, k++);
+		if (k % 2) {
+			cmd[y++] = '\\';
+		}
+	}
+
 	cmd[y++] = '"';
 #else
 	cmd[y++] = '\'';
--- /dev/null	Mon May 18 16:38:59 2015
+++ b/ext/standard/tests/general_functions/bug69646.phpt	Mon May 18 16:36:34 2015
@@ -0,0 +1,47 @@
+--TEST--
+Bug #69646 OS command injection vulnerability in escapeshellarg()
+--SKIPIF--
+<?php
+if( substr(PHP_OS, 0, 3) != "WIN" )
+  die("skip.. Windows only");
+?>
+--FILE--
+<?php
+
+$a = 'a\\';
+$b = 'b -c d\\';
+var_dump( $a, escapeshellarg($a) );
+var_dump( $b, escapeshellarg($b) );
+
+$helper_script = <<<SCRIPT
+<?php
+
+print( "--- ARG INFO ---\n" );
+var_dump( \$argv );
+
+SCRIPT;
+
+$script = dirname(__FILE__) . DIRECTORY_SEPARATOR . "arginfo.php";
+file_put_contents($script, $helper_script);
+
+$cmd =  PHP_BINARY . " " . $script . " "  . escapeshellarg($a) . " " . escapeshellarg($b);
+
+system($cmd);
+
+unlink($script);
+?>
+--EXPECTF--
+string(2) "a\"
+string(5) ""a\\""
+string(7) "b -c d\"
+string(10) ""b -c d\\""
+--- ARG INFO ---
+array(3) {
+  [0]=>
+  string(%d) "%sarginfo.php"
+  [1]=>
+  string(2) "a\"
+  [2]=>
+  string(7) "b -c d\"
+}
+
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Feb 26 14:01:37 2017 UTC