hirokawa Sun, 23 Oct 2011 13:49:54 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=318342
Log: fixed bug #60116 escapeshellcmd() cannot escape the dangerous quotes. Bug: https://bugs.php.net/60116 (Open) escapeshellcmd() cannot escape the chars which causes shell injection. Changed paths: U php/php-src/trunk/ext/standard/basic_functions.c U php/php-src/trunk/ext/standard/exec.c U php/php-src/trunk/ext/standard/exec.h Modified: php/php-src/trunk/ext/standard/basic_functions.c =================================================================== --- php/php-src/trunk/ext/standard/basic_functions.c 2011-10-23 11:54:34 UTC (rev 318341) +++ php/php-src/trunk/ext/standard/basic_functions.c 2011-10-23 13:49:54 UTC (rev 318342) @@ -3614,6 +3614,7 @@ #endif register_phpinfo_constants(INIT_FUNC_ARGS_PASSTHRU); + register_exec_constants(INIT_FUNC_ARGS_PASSTHRU); register_html_constants(INIT_FUNC_ARGS_PASSTHRU); register_string_constants(INIT_FUNC_ARGS_PASSTHRU); Modified: php/php-src/trunk/ext/standard/exec.c =================================================================== --- php/php-src/trunk/ext/standard/exec.c 2011-10-23 11:54:34 UTC (rev 318341) +++ php/php-src/trunk/ext/standard/exec.c 2011-10-23 13:49:54 UTC (rev 318342) @@ -50,6 +50,16 @@ #include <unistd.h> #endif +/* {{{ register_exec_constants + * */ +void register_exec_constants(INIT_FUNC_ARGS) +{ + REGISTER_LONG_CONSTANT("ESCAPE_CMD_PAIR", ESCAPE_CMD_PAIR, CONST_PERSISTENT|CONST_CS); + REGISTER_LONG_CONSTANT("ESCAPE_CMD_END", ESCAPE_CMD_END, CONST_PERSISTENT|CONST_CS); + REGISTER_LONG_CONSTANT("ESCAPE_CMD_ALL", ESCAPE_CMD_ALL, CONST_PERSISTENT|CONST_CS); +} +/* }}} */ + /* {{{ php_exec * If type==0, only last line of output is returned (exec) * If type==1, all lines will be printed and last lined returned (system) @@ -238,7 +248,7 @@ *NOT* safe for binary strings */ -PHPAPI char *php_escape_shell_cmd(char *str) +PHPAPI char *php_escape_shell_cmd_ex(char *str, int flag) { register int x, y, l = strlen(str); char *cmd; @@ -266,14 +276,26 @@ #ifndef PHP_WIN32 case '"': case '\'': - if (!p && (p = memchr(str + x + 1, str[x], l - x - 1))) { - /* noop */ - } else if (p && *p == str[x]) { - p = NULL; - } else { + if (flag == ESCAPE_CMD_ALL) { cmd[y++] = '\\'; + cmd[y++] = str[x]; + } else if (flag == ESCAPE_CMD_END) { + if (x == 0 || x == l - 1) { + cmd[y++] = str[x]; + } else { + cmd[y++] = '\\'; + cmd[y++] = str[x]; + } + } else { /* ESCAPE_CMD_PAIR */ + if (!p && (p = memchr(str + x + 1, str[x], l - x - 1))) { + /* noop */ + } else if (p && *p == str[x]) { + p = NULL; + } else { + cmd[y++] = '\\'; + } + cmd[y++] = str[x]; } - cmd[y++] = str[x]; break; #else /* % is Windows specific for enviromental variables, ^%PATH% will @@ -327,6 +349,14 @@ } /* }}} */ +/* {{{ php_escape_shell_cmd + */ +PHPAPI char *php_escape_shell_cmd(char *str) +{ + return php_escape_shell_cmd_ex(str, ESCAPE_CMD_PAIR); +} +/* }}} */ + /* {{{ php_escape_shell_arg */ PHPAPI char *php_escape_shell_arg(char *str) @@ -397,14 +427,15 @@ { char *command; int command_len; + long flag = ESCAPE_CMD_PAIR; char *cmd = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &command, &command_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &command, &command_len, &flag) == FAILURE) { return; } if (command_len) { - cmd = php_escape_shell_cmd(command); + cmd = php_escape_shell_cmd_ex(command, flag); RETVAL_STRING(cmd, 0); } else { RETVAL_EMPTY_STRING(); Modified: php/php-src/trunk/ext/standard/exec.h =================================================================== --- php/php-src/trunk/ext/standard/exec.h 2011-10-23 11:54:34 UTC (rev 318341) +++ php/php-src/trunk/ext/standard/exec.h 2011-10-23 13:49:54 UTC (rev 318342) @@ -21,6 +21,10 @@ #ifndef EXEC_H #define EXEC_H +#define ESCAPE_CMD_PAIR 0 +#define ESCAPE_CMD_END 1 +#define ESCAPE_CMD_ALL 2 + PHP_FUNCTION(system); PHP_FUNCTION(exec); PHP_FUNCTION(escapeshellcmd);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php