mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Fix #80774: session_name() problem with backslash
Since we do no longer URL decode cookie names[1], we must not URL encode the session name. We need to prevent broken Set-Cookie headers, by rejecting names which contain invalid characters. [1] <http://git.php.net/?p=php-src.git;a=commit;h=6559fe912661ca5ce5f0eeeb591d928451428ed0> Closes GH-6711.
This commit is contained in:
parent
6dd85f83f7
commit
d7c98ca1ac
3
NEWS
3
NEWS
@ -14,6 +14,9 @@ PHP NEWS
|
|||||||
. Fixed bug #80713 (SegFault when disabling ATTR_EMULATE_PREPARES and
|
. Fixed bug #80713 (SegFault when disabling ATTR_EMULATE_PREPARES and
|
||||||
MySQL 8.0). (Nikita)
|
MySQL 8.0). (Nikita)
|
||||||
|
|
||||||
|
- Session:
|
||||||
|
. Fixed bug #80774 (session_name() problem with backslash). (cmb)
|
||||||
|
|
||||||
04 Mar 2021, php 7.4.16
|
04 Mar 2021, php 7.4.16
|
||||||
|
|
||||||
- Core:
|
- Core:
|
||||||
|
@ -1261,13 +1261,11 @@ static void php_session_remove_cookie(void) {
|
|||||||
zend_llist_element *next;
|
zend_llist_element *next;
|
||||||
zend_llist_element *current;
|
zend_llist_element *current;
|
||||||
char *session_cookie;
|
char *session_cookie;
|
||||||
zend_string *e_session_name;
|
|
||||||
size_t session_cookie_len;
|
size_t session_cookie_len;
|
||||||
size_t len = sizeof("Set-Cookie")-1;
|
size_t len = sizeof("Set-Cookie")-1;
|
||||||
|
|
||||||
e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)));
|
ZEND_ASSERT(strpbrk(PS(session_name), "=,; \t\r\n\013\014") == NULL);
|
||||||
spprintf(&session_cookie, 0, "Set-Cookie: %s=", ZSTR_VAL(e_session_name));
|
spprintf(&session_cookie, 0, "Set-Cookie: %s=", PS(session_name));
|
||||||
zend_string_free(e_session_name);
|
|
||||||
|
|
||||||
session_cookie_len = strlen(session_cookie);
|
session_cookie_len = strlen(session_cookie);
|
||||||
current = l->head;
|
current = l->head;
|
||||||
@ -1299,7 +1297,7 @@ static int php_session_send_cookie(void) /* {{{ */
|
|||||||
{
|
{
|
||||||
smart_str ncookie = {0};
|
smart_str ncookie = {0};
|
||||||
zend_string *date_fmt = NULL;
|
zend_string *date_fmt = NULL;
|
||||||
zend_string *e_session_name, *e_id;
|
zend_string *e_id;
|
||||||
|
|
||||||
if (SG(headers_sent)) {
|
if (SG(headers_sent)) {
|
||||||
const char *output_start_filename = php_output_get_start_filename();
|
const char *output_start_filename = php_output_get_start_filename();
|
||||||
@ -1313,16 +1311,20 @@ static int php_session_send_cookie(void) /* {{{ */
|
|||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* URL encode session_name and id because they might be user supplied */
|
/* Prevent broken Set-Cookie header, because the session_name might be user supplied */
|
||||||
e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)));
|
if (strpbrk(PS(session_name), "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
|
||||||
|
php_error_docref(NULL, E_WARNING, "session.name cannot contain any of the following '=,; \\t\\r\\n\\013\\014'");
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* URL encode id because it might be user supplied */
|
||||||
e_id = php_url_encode(ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)));
|
e_id = php_url_encode(ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)));
|
||||||
|
|
||||||
smart_str_appendl(&ncookie, "Set-Cookie: ", sizeof("Set-Cookie: ")-1);
|
smart_str_appendl(&ncookie, "Set-Cookie: ", sizeof("Set-Cookie: ")-1);
|
||||||
smart_str_appendl(&ncookie, ZSTR_VAL(e_session_name), ZSTR_LEN(e_session_name));
|
smart_str_appendl(&ncookie, PS(session_name), strlen(PS(session_name)));
|
||||||
smart_str_appendc(&ncookie, '=');
|
smart_str_appendc(&ncookie, '=');
|
||||||
smart_str_appendl(&ncookie, ZSTR_VAL(e_id), ZSTR_LEN(e_id));
|
smart_str_appendl(&ncookie, ZSTR_VAL(e_id), ZSTR_LEN(e_id));
|
||||||
|
|
||||||
zend_string_release_ex(e_session_name, 0);
|
|
||||||
zend_string_release_ex(e_id, 0);
|
zend_string_release_ex(e_id, 0);
|
||||||
|
|
||||||
if (PS(cookie_lifetime) > 0) {
|
if (PS(cookie_lifetime) > 0) {
|
||||||
|
15
ext/session/tests/bug80774.phpt
Normal file
15
ext/session/tests/bug80774.phpt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
--TEST--
|
||||||
|
Bug #80774 (session_name() problem with backslash)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded('session')) die("skip session extension not available");
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
session_name("foo\\bar");
|
||||||
|
session_id('12345');
|
||||||
|
session_start();
|
||||||
|
?>
|
||||||
|
--EXPECTHEADERS--
|
||||||
|
Set-Cookie: foo\bar=12345; path=/
|
||||||
|
--EXPECT--
|
@ -48,6 +48,8 @@ string(9) "PHPSESSID"
|
|||||||
bool(true)
|
bool(true)
|
||||||
string(9) "PHPSESSID"
|
string(9) "PHPSESSID"
|
||||||
string(9) "PHPSESSID"
|
string(9) "PHPSESSID"
|
||||||
|
|
||||||
|
Warning: session_start(): session.name cannot contain any of the following '=,; \t\r\n\013\014' in %s on line %d
|
||||||
bool(true)
|
bool(true)
|
||||||
string(1) " "
|
string(1) " "
|
||||||
bool(true)
|
bool(true)
|
||||||
@ -55,6 +57,8 @@ string(1) " "
|
|||||||
|
|
||||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||||
string(1) " "
|
string(1) " "
|
||||||
|
|
||||||
|
Warning: session_start(): session.name cannot contain any of the following '=,; \t\r\n\013\014' in %s on line %d
|
||||||
bool(true)
|
bool(true)
|
||||||
string(1) " "
|
string(1) " "
|
||||||
bool(true)
|
bool(true)
|
||||||
|
Loading…
Reference in New Issue
Block a user