mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GHSA-wpj3-hf5j-x4v4: __Host-/__Secure- cookie bypass due to partial CVE-2022-31629 fix
The check happened too early as later code paths may perform more mangling rules. Move the check downwards right before adding the actual variable.
This commit is contained in:
committed by
Ben Ramsey
parent
e3c784f2bf
commit
093c08af25
@@ -54,6 +54,21 @@ static zend_always_inline void php_register_variable_quick(const char *name, siz
|
||||
zend_string_release_ex(key, 0);
|
||||
}
|
||||
|
||||
/* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host-
|
||||
* Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */
|
||||
static bool php_is_forbidden_variable_name(const char *mangled_name, size_t mangled_name_len, const char *pre_mangled_name)
|
||||
{
|
||||
if (mangled_name_len >= sizeof("__Host-")-1 && strncmp(mangled_name, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(pre_mangled_name, "__Host-", sizeof("__Host-")-1) != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mangled_name_len >= sizeof("__Secure-")-1 && strncmp(mangled_name, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(pre_mangled_name, "__Secure-", sizeof("__Secure-")-1) != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *track_vars_array)
|
||||
{
|
||||
char *p = NULL;
|
||||
@@ -104,20 +119,6 @@ PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *trac
|
||||
}
|
||||
var_len = p - var;
|
||||
|
||||
/* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- */
|
||||
if (strncmp(var, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(var_name, "__Host-", sizeof("__Host-")-1) != 0) {
|
||||
zval_ptr_dtor_nogc(val);
|
||||
free_alloca(var_orig, use_heap);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */
|
||||
if (strncmp(var, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(var_name, "__Secure-", sizeof("__Secure-")-1) != 0) {
|
||||
zval_ptr_dtor_nogc(val);
|
||||
free_alloca(var_orig, use_heap);
|
||||
return;
|
||||
}
|
||||
|
||||
if (var_len==0) { /* empty variable name, or variable name with a space in it */
|
||||
zval_ptr_dtor_nogc(val);
|
||||
free_alloca(var_orig, use_heap);
|
||||
@@ -221,6 +222,12 @@ PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *trac
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (php_is_forbidden_variable_name(index, index_len, var_name)) {
|
||||
zval_ptr_dtor_nogc(val);
|
||||
free_alloca(var_orig, use_heap);
|
||||
return;
|
||||
}
|
||||
|
||||
gpc_element_p = zend_symtable_str_find(symtable1, index, index_len);
|
||||
if (!gpc_element_p) {
|
||||
zval tmp;
|
||||
@@ -258,6 +265,12 @@ plain_var:
|
||||
zval_ptr_dtor_nogc(val);
|
||||
}
|
||||
} else {
|
||||
if (php_is_forbidden_variable_name(index, index_len, var_name)) {
|
||||
zval_ptr_dtor_nogc(val);
|
||||
free_alloca(var_orig, use_heap);
|
||||
return;
|
||||
}
|
||||
|
||||
zend_ulong idx;
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user