mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Merge branch 'PHP-8.2' into PHP-8.3
This commit is contained in:
commit
e4453dcbd2
@ -89,7 +89,7 @@
|
||||
#define FORMAT_IPV4 4
|
||||
#define FORMAT_IPV6 6
|
||||
|
||||
static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]);
|
||||
static int _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]);
|
||||
|
||||
static int php_filter_parse_int(const char *str, size_t str_len, zend_long *ret) { /* {{{ */
|
||||
zend_long ctx_value;
|
||||
@ -580,6 +580,14 @@ static int is_userinfo_valid(zend_string *str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool php_filter_is_valid_ipv6_hostname(const char *s, size_t l)
|
||||
{
|
||||
const char *e = s + l;
|
||||
const char *t = e - 1;
|
||||
|
||||
return *s == '[' && *t == ']' && _php_filter_validate_ipv6(s + 1, l - 2, NULL);
|
||||
}
|
||||
|
||||
void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
|
||||
{
|
||||
php_url *url;
|
||||
@ -600,7 +608,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
|
||||
|
||||
if (url->scheme != NULL &&
|
||||
(zend_string_equals_literal_ci(url->scheme, "http") || zend_string_equals_literal_ci(url->scheme, "https"))) {
|
||||
char *e, *s, *t;
|
||||
const char *s;
|
||||
size_t l;
|
||||
|
||||
if (url->host == NULL) {
|
||||
@ -609,17 +617,14 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
|
||||
|
||||
s = ZSTR_VAL(url->host);
|
||||
l = ZSTR_LEN(url->host);
|
||||
e = s + l;
|
||||
t = e - 1;
|
||||
|
||||
/* An IPv6 enclosed by square brackets is a valid hostname */
|
||||
if (*s == '[' && *t == ']' && _php_filter_validate_ipv6((s + 1), l - 2, NULL)) {
|
||||
php_url_free(url);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate domain
|
||||
if (!_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME)) {
|
||||
if (
|
||||
/* An IPv6 enclosed by square brackets is a valid hostname.*/
|
||||
!php_filter_is_valid_ipv6_hostname(s, l) &&
|
||||
/* Validate domain.
|
||||
* This includes a loose check for an IPv4 address. */
|
||||
!_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME)
|
||||
) {
|
||||
php_url_free(url);
|
||||
RETURN_VALIDATION_FAILED
|
||||
}
|
||||
@ -753,15 +758,15 @@ static int _php_filter_validate_ipv4(char *str, size_t str_len, int *ip) /* {{{
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]) /* {{{ */
|
||||
static int _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]) /* {{{ */
|
||||
{
|
||||
int compressed_pos = -1;
|
||||
int blocks = 0;
|
||||
int num, n, i;
|
||||
char *ipv4;
|
||||
char *end;
|
||||
const char *end;
|
||||
int ip4elm[4];
|
||||
char *s = str;
|
||||
const char *s = str;
|
||||
|
||||
if (!memchr(str, ':', str_len)) {
|
||||
return 0;
|
||||
|
41
ext/filter/tests/ghsa-w8qr-v226-r27w.phpt
Normal file
41
ext/filter/tests/ghsa-w8qr-v226-r27w.phpt
Normal file
@ -0,0 +1,41 @@
|
||||
--TEST--
|
||||
GHSA-w8qr-v226-r27w
|
||||
--EXTENSIONS--
|
||||
filter
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test(string $input) {
|
||||
var_dump(filter_var($input, FILTER_VALIDATE_URL));
|
||||
}
|
||||
|
||||
echo "--- These ones should fail ---\n";
|
||||
test("http://t[est@127.0.0.1");
|
||||
test("http://t[est@[::1]");
|
||||
test("http://t[est@[::1");
|
||||
test("http://t[est@::1]");
|
||||
test("http://php.net\\@aliyun.com/aaa.do");
|
||||
test("http://test[@2001:db8:3333:4444:5555:6666:1.2.3.4]");
|
||||
test("http://te[st@2001:db8:3333:4444:5555:6666:1.2.3.4]");
|
||||
test("http://te[st@2001:db8:3333:4444:5555:6666:1.2.3.4");
|
||||
|
||||
echo "--- These ones should work ---\n";
|
||||
test("http://test@127.0.0.1");
|
||||
test("http://test@[2001:db8:3333:4444:5555:6666:1.2.3.4]");
|
||||
test("http://test@[::1]");
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--- These ones should fail ---
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
--- These ones should work ---
|
||||
string(21) "http://test@127.0.0.1"
|
||||
string(50) "http://test@[2001:db8:3333:4444:5555:6666:1.2.3.4]"
|
||||
string(17) "http://test@[::1]"
|
@ -592,48 +592,39 @@ static void append_win_escaped_arg(smart_str *str, zend_string *arg, bool is_cmd
|
||||
smart_str_appendc(str, '"');
|
||||
}
|
||||
|
||||
static inline int stricmp_end(const char* suffix, const char* str) {
|
||||
size_t suffix_len = strlen(suffix);
|
||||
size_t str_len = strlen(str);
|
||||
|
||||
if (suffix_len > str_len) {
|
||||
return -1; /* Suffix is longer than string, cannot match. */
|
||||
}
|
||||
|
||||
/* Compare the end of the string with the suffix, ignoring case. */
|
||||
return _stricmp(str + (str_len - suffix_len), suffix);
|
||||
}
|
||||
|
||||
static bool is_executed_by_cmd(const char *prog_name)
|
||||
static bool is_executed_by_cmd(const char *prog_name, size_t prog_name_length)
|
||||
{
|
||||
/* If program name is cmd.exe, then return true. */
|
||||
if (_stricmp("cmd.exe", prog_name) == 0 || _stricmp("cmd", prog_name) == 0
|
||||
|| stricmp_end("\\cmd.exe", prog_name) == 0 || stricmp_end("\\cmd", prog_name) == 0) {
|
||||
return true;
|
||||
}
|
||||
size_t out_len;
|
||||
WCHAR long_name[MAX_PATH];
|
||||
WCHAR full_name[MAX_PATH];
|
||||
LPWSTR file_part = NULL;
|
||||
|
||||
/* Find the last occurrence of the directory separator (backslash or forward slash). */
|
||||
char *last_separator = strrchr(prog_name, '\\');
|
||||
char *last_separator_fwd = strrchr(prog_name, '/');
|
||||
if (last_separator_fwd && (!last_separator || last_separator < last_separator_fwd)) {
|
||||
last_separator = last_separator_fwd;
|
||||
wchar_t *prog_name_wide = php_win32_cp_conv_any_to_w(prog_name, prog_name_length, &out_len);
|
||||
|
||||
if (GetLongPathNameW(prog_name_wide, long_name, MAX_PATH) == 0) {
|
||||
/* This can fail for example with ERROR_FILE_NOT_FOUND (short path resolution only works for existing files)
|
||||
* in which case we'll pass the path verbatim to the FullPath transformation. */
|
||||
lstrcpynW(long_name, prog_name_wide, MAX_PATH);
|
||||
}
|
||||
|
||||
/* Find the last dot in the filename after the last directory separator. */
|
||||
char *extension = NULL;
|
||||
if (last_separator != NULL) {
|
||||
extension = strrchr(last_separator, '.');
|
||||
} else {
|
||||
extension = strrchr(prog_name, '.');
|
||||
}
|
||||
free(prog_name_wide);
|
||||
prog_name_wide = NULL;
|
||||
|
||||
if (extension == NULL || extension == prog_name) {
|
||||
/* No file extension found, it is not batch file. */
|
||||
if (GetFullPathNameW(long_name, MAX_PATH, full_name, &file_part) == 0 || file_part == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if the file extension is ".bat" or ".cmd" which is always executed by cmd.exe. */
|
||||
return _stricmp(extension, ".bat") == 0 || _stricmp(extension, ".cmd") == 0;
|
||||
bool uses_cmd = false;
|
||||
if (_wcsicmp(file_part, L"cmd.exe") == 0 || _wcsicmp(file_part, L"cmd") == 0) {
|
||||
uses_cmd = true;
|
||||
} else {
|
||||
const WCHAR *extension_dot = wcsrchr(file_part, L'.');
|
||||
if (extension_dot && (_wcsicmp(extension_dot, L".bat") == 0 || _wcsicmp(extension_dot, L".cmd") == 0)) {
|
||||
uses_cmd = true;
|
||||
}
|
||||
}
|
||||
|
||||
return uses_cmd;
|
||||
}
|
||||
|
||||
static zend_string *create_win_command_from_args(HashTable *args)
|
||||
@ -652,7 +643,7 @@ static zend_string *create_win_command_from_args(HashTable *args)
|
||||
}
|
||||
|
||||
if (is_prog_name) {
|
||||
is_cmd_execution = is_executed_by_cmd(ZSTR_VAL(arg_str));
|
||||
is_cmd_execution = is_executed_by_cmd(ZSTR_VAL(arg_str), ZSTR_LEN(arg_str));
|
||||
} else {
|
||||
smart_str_appendc(&str, ' ');
|
||||
}
|
||||
|
@ -0,0 +1,56 @@
|
||||
--TEST--
|
||||
GHSA-9fcc-425m-g385 - bypass CVE-2024-1874 - batch file variation
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if( substr(PHP_OS, 0, 3) != "WIN" )
|
||||
die('skip Run only on Windows');
|
||||
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$batch_file_content = <<<EOT
|
||||
@echo off
|
||||
powershell -Command "Write-Output '%0%'"
|
||||
powershell -Command "Write-Output '%1%'"
|
||||
EOT;
|
||||
$batch_file_path = __DIR__ . '/ghsa-9fcc-425m-g385_001.bat';
|
||||
|
||||
file_put_contents($batch_file_path, $batch_file_content);
|
||||
|
||||
$descriptorspec = [STDIN, STDOUT, STDOUT];
|
||||
|
||||
$proc = proc_open([$batch_file_path . ".", "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open([$batch_file_path . " ", "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open([$batch_file_path . ". ", "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open([$batch_file_path . ". ... ", "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open([$batch_file_path . ". ... . ", "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open([$batch_file_path . ". ... . .", "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
proc_open([$batch_file_path . ". .\\.. . .", "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
'"%sghsa-9fcc-425m-g385_001.bat."' is not recognized as an internal or external command,
|
||||
operable program or batch file.
|
||||
%sghsa-9fcc-425m-g385_001.bat
|
||||
"¬epad.exe
|
||||
%sghsa-9fcc-425m-g385_001.bat.
|
||||
"¬epad.exe
|
||||
%sghsa-9fcc-425m-g385_001.bat. ...
|
||||
"¬epad.exe
|
||||
%sghsa-9fcc-425m-g385_001.bat. ... .
|
||||
"¬epad.exe
|
||||
'"%sghsa-9fcc-425m-g385_001.bat. ... . ."' is not recognized as an internal or external command,
|
||||
operable program or batch file.
|
||||
|
||||
Warning: proc_open(): CreateProcess failed, error code: 2 in %s on line %d
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__ . '/ghsa-9fcc-425m-g385_001.bat');
|
||||
?>
|
@ -0,0 +1,66 @@
|
||||
--TEST--
|
||||
GHSA-9fcc-425m-g385 - bypass CVE-2024-1874 - cmd.exe variation
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if( substr(PHP_OS, 0, 3) != "WIN" )
|
||||
die('skip Run only on Windows');
|
||||
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$batch_file_content = <<<EOT
|
||||
@echo off
|
||||
powershell -Command "Write-Output '%0%'"
|
||||
powershell -Command "Write-Output '%1%'"
|
||||
EOT;
|
||||
$batch_file_path = __DIR__ . '/ghsa-9fcc-425m-g385_002.bat';
|
||||
|
||||
file_put_contents($batch_file_path, $batch_file_content);
|
||||
|
||||
$descriptorspec = [STDIN, STDOUT, STDOUT];
|
||||
|
||||
$proc = proc_open(["cmd.exe", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open(["cmd.exe ", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open(["cmd.exe. ", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open(["cmd.exe. ... ", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open(["\\cmd.exe. ... ", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
|
||||
$proc = proc_open(["cmd", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open(["cmd ", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
proc_close($proc);
|
||||
$proc = proc_open(["cmd. ", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
$proc = proc_open(["cmd. ... ", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
$proc = proc_open(["\\cmd. ... ", "/c", $batch_file_path, "\"¬epad.exe"], $descriptorspec, $pipes);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
%sghsa-9fcc-425m-g385_002.bat
|
||||
"¬epad.exe
|
||||
%sghsa-9fcc-425m-g385_002.bat
|
||||
"¬epad.exe
|
||||
%sghsa-9fcc-425m-g385_002.bat
|
||||
"¬epad.exe
|
||||
%sghsa-9fcc-425m-g385_002.bat
|
||||
"¬epad.exe
|
||||
|
||||
Warning: proc_open(): CreateProcess failed, error code: 2 in %s on line %d
|
||||
%sghsa-9fcc-425m-g385_002.bat
|
||||
"¬epad.exe
|
||||
%sghsa-9fcc-425m-g385_002.bat
|
||||
"¬epad.exe
|
||||
|
||||
Warning: proc_open(): CreateProcess failed, error code: 2 in %s on line %d
|
||||
|
||||
Warning: proc_open(): CreateProcess failed, error code: 2 in %s on line %d
|
||||
|
||||
Warning: proc_open(): CreateProcess failed, error code: 2 in %s on line %d
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__ . '/ghsa-9fcc-425m-g385_002.bat');
|
||||
?>
|
@ -0,0 +1,550 @@
|
||||
--TEST--
|
||||
GHSA-9fcc-425m-g385 - bypass CVE-2024-1874 - exhaustive suffix test
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if( substr(PHP_OS, 0, 3) != "WIN" )
|
||||
die('skip Run only on Windows');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$batch_file_content = <<<EOT
|
||||
@echo off
|
||||
powershell -Command "Write-Output '%0%'"
|
||||
powershell -Command "Write-Output '%1%'"
|
||||
EOT;
|
||||
$batch_file_path = __DIR__ . '/ghsa-9fcc-425m-g385_003.bat';
|
||||
|
||||
file_put_contents($batch_file_path, $batch_file_content);
|
||||
|
||||
$descriptorspec = [STDIN, STDOUT, STDOUT];
|
||||
|
||||
for ($i = 1; $i <= 255; $i++) {
|
||||
echo "Testing $i\n";
|
||||
try {
|
||||
$proc = @proc_open([$batch_file_path . chr($i), "\"¬epad.exe"], $descriptorspec, $pipes, null, null, array("bypass_shell" => true));
|
||||
var_dump($proc);
|
||||
proc_close($proc);
|
||||
} catch (Error) {}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Testing 1
|
||||
bool(false)
|
||||
Testing 2
|
||||
bool(false)
|
||||
Testing 3
|
||||
bool(false)
|
||||
Testing 4
|
||||
bool(false)
|
||||
Testing 5
|
||||
bool(false)
|
||||
Testing 6
|
||||
bool(false)
|
||||
Testing 7
|
||||
bool(false)
|
||||
Testing 8
|
||||
bool(false)
|
||||
Testing 9
|
||||
bool(false)
|
||||
Testing 10
|
||||
bool(false)
|
||||
Testing 11
|
||||
bool(false)
|
||||
Testing 12
|
||||
bool(false)
|
||||
Testing 13
|
||||
bool(false)
|
||||
Testing 14
|
||||
bool(false)
|
||||
Testing 15
|
||||
bool(false)
|
||||
Testing 16
|
||||
bool(false)
|
||||
Testing 17
|
||||
bool(false)
|
||||
Testing 18
|
||||
bool(false)
|
||||
Testing 19
|
||||
bool(false)
|
||||
Testing 20
|
||||
bool(false)
|
||||
Testing 21
|
||||
bool(false)
|
||||
Testing 22
|
||||
bool(false)
|
||||
Testing 23
|
||||
bool(false)
|
||||
Testing 24
|
||||
bool(false)
|
||||
Testing 25
|
||||
bool(false)
|
||||
Testing 26
|
||||
bool(false)
|
||||
Testing 27
|
||||
bool(false)
|
||||
Testing 28
|
||||
bool(false)
|
||||
Testing 29
|
||||
bool(false)
|
||||
Testing 30
|
||||
bool(false)
|
||||
Testing 31
|
||||
bool(false)
|
||||
Testing 32
|
||||
resource(%d) of type (process)
|
||||
%s.bat
|
||||
"¬epad.exe
|
||||
Testing 33
|
||||
bool(false)
|
||||
Testing 34
|
||||
bool(false)
|
||||
Testing 35
|
||||
bool(false)
|
||||
Testing 36
|
||||
bool(false)
|
||||
Testing 37
|
||||
bool(false)
|
||||
Testing 38
|
||||
bool(false)
|
||||
Testing 39
|
||||
bool(false)
|
||||
Testing 40
|
||||
bool(false)
|
||||
Testing 41
|
||||
bool(false)
|
||||
Testing 42
|
||||
bool(false)
|
||||
Testing 43
|
||||
bool(false)
|
||||
Testing 44
|
||||
bool(false)
|
||||
Testing 45
|
||||
bool(false)
|
||||
Testing 46
|
||||
resource(%d) of type (process)
|
||||
'"%s.bat."' is not recognized as an internal or external command,
|
||||
operable program or batch file.
|
||||
Testing 47
|
||||
bool(false)
|
||||
Testing 48
|
||||
bool(false)
|
||||
Testing 49
|
||||
bool(false)
|
||||
Testing 50
|
||||
bool(false)
|
||||
Testing 51
|
||||
bool(false)
|
||||
Testing 52
|
||||
bool(false)
|
||||
Testing 53
|
||||
bool(false)
|
||||
Testing 54
|
||||
bool(false)
|
||||
Testing 55
|
||||
bool(false)
|
||||
Testing 56
|
||||
bool(false)
|
||||
Testing 57
|
||||
bool(false)
|
||||
Testing 58
|
||||
bool(false)
|
||||
Testing 59
|
||||
bool(false)
|
||||
Testing 60
|
||||
bool(false)
|
||||
Testing 61
|
||||
bool(false)
|
||||
Testing 62
|
||||
bool(false)
|
||||
Testing 63
|
||||
bool(false)
|
||||
Testing 64
|
||||
bool(false)
|
||||
Testing 65
|
||||
bool(false)
|
||||
Testing 66
|
||||
bool(false)
|
||||
Testing 67
|
||||
bool(false)
|
||||
Testing 68
|
||||
bool(false)
|
||||
Testing 69
|
||||
bool(false)
|
||||
Testing 70
|
||||
bool(false)
|
||||
Testing 71
|
||||
bool(false)
|
||||
Testing 72
|
||||
bool(false)
|
||||
Testing 73
|
||||
bool(false)
|
||||
Testing 74
|
||||
bool(false)
|
||||
Testing 75
|
||||
bool(false)
|
||||
Testing 76
|
||||
bool(false)
|
||||
Testing 77
|
||||
bool(false)
|
||||
Testing 78
|
||||
bool(false)
|
||||
Testing 79
|
||||
bool(false)
|
||||
Testing 80
|
||||
bool(false)
|
||||
Testing 81
|
||||
bool(false)
|
||||
Testing 82
|
||||
bool(false)
|
||||
Testing 83
|
||||
bool(false)
|
||||
Testing 84
|
||||
bool(false)
|
||||
Testing 85
|
||||
bool(false)
|
||||
Testing 86
|
||||
bool(false)
|
||||
Testing 87
|
||||
bool(false)
|
||||
Testing 88
|
||||
bool(false)
|
||||
Testing 89
|
||||
bool(false)
|
||||
Testing 90
|
||||
bool(false)
|
||||
Testing 91
|
||||
bool(false)
|
||||
Testing 92
|
||||
bool(false)
|
||||
Testing 93
|
||||
bool(false)
|
||||
Testing 94
|
||||
bool(false)
|
||||
Testing 95
|
||||
bool(false)
|
||||
Testing 96
|
||||
bool(false)
|
||||
Testing 97
|
||||
bool(false)
|
||||
Testing 98
|
||||
bool(false)
|
||||
Testing 99
|
||||
bool(false)
|
||||
Testing 100
|
||||
bool(false)
|
||||
Testing 101
|
||||
bool(false)
|
||||
Testing 102
|
||||
bool(false)
|
||||
Testing 103
|
||||
bool(false)
|
||||
Testing 104
|
||||
bool(false)
|
||||
Testing 105
|
||||
bool(false)
|
||||
Testing 106
|
||||
bool(false)
|
||||
Testing 107
|
||||
bool(false)
|
||||
Testing 108
|
||||
bool(false)
|
||||
Testing 109
|
||||
bool(false)
|
||||
Testing 110
|
||||
bool(false)
|
||||
Testing 111
|
||||
bool(false)
|
||||
Testing 112
|
||||
bool(false)
|
||||
Testing 113
|
||||
bool(false)
|
||||
Testing 114
|
||||
bool(false)
|
||||
Testing 115
|
||||
bool(false)
|
||||
Testing 116
|
||||
bool(false)
|
||||
Testing 117
|
||||
bool(false)
|
||||
Testing 118
|
||||
bool(false)
|
||||
Testing 119
|
||||
bool(false)
|
||||
Testing 120
|
||||
bool(false)
|
||||
Testing 121
|
||||
bool(false)
|
||||
Testing 122
|
||||
bool(false)
|
||||
Testing 123
|
||||
bool(false)
|
||||
Testing 124
|
||||
bool(false)
|
||||
Testing 125
|
||||
bool(false)
|
||||
Testing 126
|
||||
bool(false)
|
||||
Testing 127
|
||||
bool(false)
|
||||
Testing 128
|
||||
bool(false)
|
||||
Testing 129
|
||||
bool(false)
|
||||
Testing 130
|
||||
bool(false)
|
||||
Testing 131
|
||||
bool(false)
|
||||
Testing 132
|
||||
bool(false)
|
||||
Testing 133
|
||||
bool(false)
|
||||
Testing 134
|
||||
bool(false)
|
||||
Testing 135
|
||||
bool(false)
|
||||
Testing 136
|
||||
bool(false)
|
||||
Testing 137
|
||||
bool(false)
|
||||
Testing 138
|
||||
bool(false)
|
||||
Testing 139
|
||||
bool(false)
|
||||
Testing 140
|
||||
bool(false)
|
||||
Testing 141
|
||||
bool(false)
|
||||
Testing 142
|
||||
bool(false)
|
||||
Testing 143
|
||||
bool(false)
|
||||
Testing 144
|
||||
bool(false)
|
||||
Testing 145
|
||||
bool(false)
|
||||
Testing 146
|
||||
bool(false)
|
||||
Testing 147
|
||||
bool(false)
|
||||
Testing 148
|
||||
bool(false)
|
||||
Testing 149
|
||||
bool(false)
|
||||
Testing 150
|
||||
bool(false)
|
||||
Testing 151
|
||||
bool(false)
|
||||
Testing 152
|
||||
bool(false)
|
||||
Testing 153
|
||||
bool(false)
|
||||
Testing 154
|
||||
bool(false)
|
||||
Testing 155
|
||||
bool(false)
|
||||
Testing 156
|
||||
bool(false)
|
||||
Testing 157
|
||||
bool(false)
|
||||
Testing 158
|
||||
bool(false)
|
||||
Testing 159
|
||||
bool(false)
|
||||
Testing 160
|
||||
bool(false)
|
||||
Testing 161
|
||||
bool(false)
|
||||
Testing 162
|
||||
bool(false)
|
||||
Testing 163
|
||||
bool(false)
|
||||
Testing 164
|
||||
bool(false)
|
||||
Testing 165
|
||||
bool(false)
|
||||
Testing 166
|
||||
bool(false)
|
||||
Testing 167
|
||||
bool(false)
|
||||
Testing 168
|
||||
bool(false)
|
||||
Testing 169
|
||||
bool(false)
|
||||
Testing 170
|
||||
bool(false)
|
||||
Testing 171
|
||||
bool(false)
|
||||
Testing 172
|
||||
bool(false)
|
||||
Testing 173
|
||||
bool(false)
|
||||
Testing 174
|
||||
bool(false)
|
||||
Testing 175
|
||||
bool(false)
|
||||
Testing 176
|
||||
bool(false)
|
||||
Testing 177
|
||||
bool(false)
|
||||
Testing 178
|
||||
bool(false)
|
||||
Testing 179
|
||||
bool(false)
|
||||
Testing 180
|
||||
bool(false)
|
||||
Testing 181
|
||||
bool(false)
|
||||
Testing 182
|
||||
bool(false)
|
||||
Testing 183
|
||||
bool(false)
|
||||
Testing 184
|
||||
bool(false)
|
||||
Testing 185
|
||||
bool(false)
|
||||
Testing 186
|
||||
bool(false)
|
||||
Testing 187
|
||||
bool(false)
|
||||
Testing 188
|
||||
bool(false)
|
||||
Testing 189
|
||||
bool(false)
|
||||
Testing 190
|
||||
bool(false)
|
||||
Testing 191
|
||||
bool(false)
|
||||
Testing 192
|
||||
bool(false)
|
||||
Testing 193
|
||||
bool(false)
|
||||
Testing 194
|
||||
bool(false)
|
||||
Testing 195
|
||||
bool(false)
|
||||
Testing 196
|
||||
bool(false)
|
||||
Testing 197
|
||||
bool(false)
|
||||
Testing 198
|
||||
bool(false)
|
||||
Testing 199
|
||||
bool(false)
|
||||
Testing 200
|
||||
bool(false)
|
||||
Testing 201
|
||||
bool(false)
|
||||
Testing 202
|
||||
bool(false)
|
||||
Testing 203
|
||||
bool(false)
|
||||
Testing 204
|
||||
bool(false)
|
||||
Testing 205
|
||||
bool(false)
|
||||
Testing 206
|
||||
bool(false)
|
||||
Testing 207
|
||||
bool(false)
|
||||
Testing 208
|
||||
bool(false)
|
||||
Testing 209
|
||||
bool(false)
|
||||
Testing 210
|
||||
bool(false)
|
||||
Testing 211
|
||||
bool(false)
|
||||
Testing 212
|
||||
bool(false)
|
||||
Testing 213
|
||||
bool(false)
|
||||
Testing 214
|
||||
bool(false)
|
||||
Testing 215
|
||||
bool(false)
|
||||
Testing 216
|
||||
bool(false)
|
||||
Testing 217
|
||||
bool(false)
|
||||
Testing 218
|
||||
bool(false)
|
||||
Testing 219
|
||||
bool(false)
|
||||
Testing 220
|
||||
bool(false)
|
||||
Testing 221
|
||||
bool(false)
|
||||
Testing 222
|
||||
bool(false)
|
||||
Testing 223
|
||||
bool(false)
|
||||
Testing 224
|
||||
bool(false)
|
||||
Testing 225
|
||||
bool(false)
|
||||
Testing 226
|
||||
bool(false)
|
||||
Testing 227
|
||||
bool(false)
|
||||
Testing 228
|
||||
bool(false)
|
||||
Testing 229
|
||||
bool(false)
|
||||
Testing 230
|
||||
bool(false)
|
||||
Testing 231
|
||||
bool(false)
|
||||
Testing 232
|
||||
bool(false)
|
||||
Testing 233
|
||||
bool(false)
|
||||
Testing 234
|
||||
bool(false)
|
||||
Testing 235
|
||||
bool(false)
|
||||
Testing 236
|
||||
bool(false)
|
||||
Testing 237
|
||||
bool(false)
|
||||
Testing 238
|
||||
bool(false)
|
||||
Testing 239
|
||||
bool(false)
|
||||
Testing 240
|
||||
bool(false)
|
||||
Testing 241
|
||||
bool(false)
|
||||
Testing 242
|
||||
bool(false)
|
||||
Testing 243
|
||||
bool(false)
|
||||
Testing 244
|
||||
bool(false)
|
||||
Testing 245
|
||||
bool(false)
|
||||
Testing 246
|
||||
bool(false)
|
||||
Testing 247
|
||||
bool(false)
|
||||
Testing 248
|
||||
bool(false)
|
||||
Testing 249
|
||||
bool(false)
|
||||
Testing 250
|
||||
bool(false)
|
||||
Testing 251
|
||||
bool(false)
|
||||
Testing 252
|
||||
bool(false)
|
||||
Testing 253
|
||||
bool(false)
|
||||
Testing 254
|
||||
bool(false)
|
||||
Testing 255
|
||||
bool(false)
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__ . '/ghsa-9fcc-425m-g385_003.bat');
|
||||
?>
|
@ -1796,8 +1796,13 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
/* Apache CGI will pass the query string to the command line if it doesn't contain a '='.
|
||||
* This can create an issue where a malicious request can pass command line arguments to
|
||||
* the executable. Ideally we skip argument parsing when we're in cgi or fastcgi mode,
|
||||
* but that breaks PHP scripts on Linux with a hashbang: `#!/php-cgi -d option=value`.
|
||||
* Therefore, this code only prevents passing arguments if the query string starts with a '-'.
|
||||
* Similarly, scripts spawned in subprocesses on Windows may have the same issue. */
|
||||
if((query_string = getenv("QUERY_STRING")) != NULL && strchr(query_string, '=') == NULL) {
|
||||
/* we've got query string that has no = - apache CGI will pass it to command line */
|
||||
unsigned char *p;
|
||||
decoded_query_string = strdup(query_string);
|
||||
php_url_decode(decoded_query_string, strlen(decoded_query_string));
|
||||
@ -1807,6 +1812,22 @@ int main(int argc, char *argv[])
|
||||
if(*p == '-') {
|
||||
skip_getopt = 1;
|
||||
}
|
||||
|
||||
/* On Windows we have to take into account the "best fit" mapping behaviour. */
|
||||
#ifdef PHP_WIN32
|
||||
if (*p >= 0x80) {
|
||||
wchar_t wide_buf[1];
|
||||
wide_buf[0] = *p;
|
||||
char char_buf[4];
|
||||
size_t wide_buf_len = sizeof(wide_buf) / sizeof(wide_buf[0]);
|
||||
size_t char_buf_len = sizeof(char_buf) / sizeof(char_buf[0]);
|
||||
if (WideCharToMultiByte(CP_ACP, 0, wide_buf, wide_buf_len, char_buf, char_buf_len, NULL, NULL) == 0
|
||||
|| char_buf[0] == '-') {
|
||||
skip_getopt = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
free(decoded_query_string);
|
||||
}
|
||||
|
||||
|
38
sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt
Normal file
38
sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt
Normal file
@ -0,0 +1,38 @@
|
||||
--TEST--
|
||||
GHSA-3qgc-jrrr-25jv
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include 'skipif.inc';
|
||||
if (PHP_OS_FAMILY !== "Windows") die("skip Only for Windows");
|
||||
|
||||
$codepage = trim(shell_exec("powershell Get-ItemPropertyValue HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage ACP"));
|
||||
if ($codepage !== '932' && $codepage !== '936' && $codepage !== '950') die("skip Wrong codepage");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
include 'include.inc';
|
||||
|
||||
$filename = __DIR__."/GHSA-3qgc-jrrr-25jv_tmp.php";
|
||||
$script = '<?php echo "hello "; echo "world"; ?>';
|
||||
file_put_contents($filename, $script);
|
||||
|
||||
$php = get_cgi_path();
|
||||
reset_env_vars();
|
||||
|
||||
putenv("SERVER_NAME=Test");
|
||||
putenv("SCRIPT_FILENAME=$filename");
|
||||
putenv("QUERY_STRING=%ads");
|
||||
putenv("REDIRECT_STATUS=1");
|
||||
|
||||
passthru("$php -s");
|
||||
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__."/GHSA-3qgc-jrrr-25jv_tmp.php");
|
||||
?>
|
||||
--EXPECTF--
|
||||
X-Powered-By: PHP/%s
|
||||
Content-type: %s
|
||||
|
||||
hello world
|
Loading…
Reference in New Issue
Block a user