mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.3'
This commit is contained in:
commit
bda372fc6c
8 changed files with 819 additions and 51 deletions
|
@ -89,7 +89,7 @@
|
||||||
#define FORMAT_IPV4 4
|
#define FORMAT_IPV4 4
|
||||||
#define FORMAT_IPV6 6
|
#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) { /* {{{ */
|
static int php_filter_parse_int(const char *str, size_t str_len, zend_long *ret) { /* {{{ */
|
||||||
zend_long ctx_value;
|
zend_long ctx_value;
|
||||||
|
@ -580,6 +580,14 @@ static int is_userinfo_valid(zend_string *str)
|
||||||
return 1;
|
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) /* {{{ */
|
void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
|
||||||
{
|
{
|
||||||
php_url *url;
|
php_url *url;
|
||||||
|
@ -600,7 +608,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
|
||||||
|
|
||||||
if (url->scheme != NULL &&
|
if (url->scheme != NULL &&
|
||||||
(zend_string_equals_literal_ci(url->scheme, "http") || zend_string_equals_literal_ci(url->scheme, "https"))) {
|
(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;
|
size_t l;
|
||||||
|
|
||||||
if (url->host == NULL) {
|
if (url->host == NULL) {
|
||||||
|
@ -609,17 +617,14 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
|
||||||
|
|
||||||
s = ZSTR_VAL(url->host);
|
s = ZSTR_VAL(url->host);
|
||||||
l = ZSTR_LEN(url->host);
|
l = ZSTR_LEN(url->host);
|
||||||
e = s + l;
|
|
||||||
t = e - 1;
|
|
||||||
|
|
||||||
/* An IPv6 enclosed by square brackets is a valid hostname */
|
if (
|
||||||
if (*s == '[' && *t == ']' && _php_filter_validate_ipv6((s + 1), l - 2, NULL)) {
|
/* An IPv6 enclosed by square brackets is a valid hostname.*/
|
||||||
php_url_free(url);
|
!php_filter_is_valid_ipv6_hostname(s, l) &&
|
||||||
return;
|
/* Validate domain.
|
||||||
}
|
* This includes a loose check for an IPv4 address. */
|
||||||
|
!_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME)
|
||||||
// Validate domain
|
) {
|
||||||
if (!_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME)) {
|
|
||||||
php_url_free(url);
|
php_url_free(url);
|
||||||
RETURN_VALIDATION_FAILED
|
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 compressed_pos = -1;
|
||||||
int blocks = 0;
|
int blocks = 0;
|
||||||
int num, n, i;
|
int num, n, i;
|
||||||
char *ipv4;
|
char *ipv4;
|
||||||
char *end;
|
const char *end;
|
||||||
int ip4elm[4];
|
int ip4elm[4];
|
||||||
char *s = str;
|
const char *s = str;
|
||||||
|
|
||||||
if (!memchr(str, ':', str_len)) {
|
if (!memchr(str, ':', str_len)) {
|
||||||
return 0;
|
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]"
|
|
@ -586,48 +586,39 @@ static void append_win_escaped_arg(smart_str *str, zend_string *arg, bool is_cmd
|
||||||
smart_str_appendc(str, '"');
|
smart_str_appendc(str, '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int stricmp_end(const char* suffix, const char* str) {
|
static bool is_executed_by_cmd(const char *prog_name, size_t prog_name_length)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
/* If program name is cmd.exe, then return true. */
|
size_t out_len;
|
||||||
if (_stricmp("cmd.exe", prog_name) == 0 || _stricmp("cmd", prog_name) == 0
|
WCHAR long_name[MAX_PATH];
|
||||||
|| stricmp_end("\\cmd.exe", prog_name) == 0 || stricmp_end("\\cmd", prog_name) == 0) {
|
WCHAR full_name[MAX_PATH];
|
||||||
return true;
|
LPWSTR file_part = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the last occurrence of the directory separator (backslash or forward slash). */
|
wchar_t *prog_name_wide = php_win32_cp_conv_any_to_w(prog_name, prog_name_length, &out_len);
|
||||||
char *last_separator = strrchr(prog_name, '\\');
|
|
||||||
char *last_separator_fwd = strrchr(prog_name, '/');
|
if (GetLongPathNameW(prog_name_wide, long_name, MAX_PATH) == 0) {
|
||||||
if (last_separator_fwd && (!last_separator || last_separator < last_separator_fwd)) {
|
/* This can fail for example with ERROR_FILE_NOT_FOUND (short path resolution only works for existing files)
|
||||||
last_separator = last_separator_fwd;
|
* 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. */
|
free(prog_name_wide);
|
||||||
char *extension = NULL;
|
prog_name_wide = NULL;
|
||||||
if (last_separator != NULL) {
|
|
||||||
extension = strrchr(last_separator, '.');
|
|
||||||
} else {
|
|
||||||
extension = strrchr(prog_name, '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extension == NULL || extension == prog_name) {
|
if (GetFullPathNameW(long_name, MAX_PATH, full_name, &file_part) == 0 || file_part == NULL) {
|
||||||
/* No file extension found, it is not batch file. */
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the file extension is ".bat" or ".cmd" which is always executed by cmd.exe. */
|
bool uses_cmd = false;
|
||||||
return _stricmp(extension, ".bat") == 0 || _stricmp(extension, ".cmd") == 0;
|
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)
|
static zend_string *create_win_command_from_args(HashTable *args)
|
||||||
|
@ -646,7 +637,7 @@ static zend_string *create_win_command_from_args(HashTable *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_prog_name) {
|
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 {
|
} else {
|
||||||
smart_str_appendc(&str, ' ');
|
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) {
|
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;
|
unsigned char *p;
|
||||||
decoded_query_string = strdup(query_string);
|
decoded_query_string = strdup(query_string);
|
||||||
php_url_decode(decoded_query_string, strlen(decoded_query_string));
|
php_url_decode(decoded_query_string, strlen(decoded_query_string));
|
||||||
|
@ -1807,6 +1812,22 @@ int main(int argc, char *argv[])
|
||||||
if(*p == '-') {
|
if(*p == '-') {
|
||||||
skip_getopt = 1;
|
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);
|
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…
Add table
Add a link
Reference in a new issue