diff --git a/ext/session/session.c b/ext/session/session.c index 74a7f4a1da70b..3cdb6606626bb 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1228,7 +1228,7 @@ static void php_session_remove_cookie(TSRMLS_D) { static void php_session_send_cookie(TSRMLS_D) /* {{{ */ { - smart_str ncookie = {0}; + smart_str ncookie = {0}, dcookie = {0}; char *date_fmt = NULL; char *e_session_name, *e_id; @@ -1244,6 +1244,39 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */ return; } + /* Try to remove offensive cookie to prevent DoS */ + e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)), NULL); + smart_str_appends(&dcookie, COOKIE_SET_COOKIE); + smart_str_appends(&dcookie, e_session_name); + smart_str_appends(&dcookie, "[]="); + date_fmt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC); + smart_str_appends(&dcookie, COOKIE_EXPIRES); + smart_str_appends(&dcookie, date_fmt); + efree(date_fmt); + + + if (PS(cookie_path)[0]) { + smart_str_appends(&dcookie, COOKIE_PATH); + smart_str_appends(&dcookie, PS(cookie_path)); + } + + if (PS(cookie_domain)[0]) { + smart_str_appends(&dcookie, COOKIE_DOMAIN); + smart_str_appends(&dcookie, PS(cookie_domain)); + } + + if (PS(cookie_secure)) { + smart_str_appends(&dcookie, COOKIE_SECURE); + } + + if (PS(cookie_httponly)) { + smart_str_appends(&dcookie, COOKIE_HTTPONLY); + } + + smart_str_0(&dcookie); + efree(e_session_name); + sapi_add_header_ex(dcookie.c, dcookie.len, 0, 0 TSRMLS_CC); + /* URL encode session_name and id because they might be user supplied */ e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)), NULL); e_id = php_url_encode(PS(id), strlen(PS(id)), NULL); @@ -1327,9 +1360,16 @@ PHPAPI const ps_serializer *_php_find_ps_serializer(char *name TSRMLS_DC) /* {{{ } /* }}} */ -#define PPID2SID \ - convert_to_string((*ppid)); \ - PS(id) = estrndup(Z_STRVAL_PP(ppid), Z_STRLEN_PP(ppid)) +static void ppid2sid(zval **ppid TSRMLS_DC) { + if (Z_TYPE_PP(ppid) != IS_STRING) { + PS(id) = NULL; + PS(send_cookie) = 1; + } else { + convert_to_string((*ppid)); + PS(id) = estrndup(Z_STRVAL_PP(ppid), Z_STRLEN_PP(ppid)); + PS(send_cookie) = 0; + } +} static void php_session_reset_id(TSRMLS_D) /* {{{ */ { @@ -1418,9 +1458,8 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */ Z_TYPE_PP(data) == IS_ARRAY && zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS ) { - PPID2SID; + ppid2sid(ppid TSRMLS_CC); PS(apply_trans_sid) = 0; - PS(send_cookie) = 0; PS(define_sid) = 0; } @@ -1429,8 +1468,7 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */ Z_TYPE_PP(data) == IS_ARRAY && zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS ) { - PPID2SID; - PS(send_cookie) = 0; + ppid2sid(ppid TSRMLS_CC); } if (!PS(use_only_cookies) && !PS(id) && @@ -1438,8 +1476,7 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */ Z_TYPE_PP(data) == IS_ARRAY && zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS ) { - PPID2SID; - PS(send_cookie) = 0; + ppid2sid(ppid TSRMLS_CC); } } diff --git a/ext/session/tests/bug66827.phpt b/ext/session/tests/bug66827.phpt new file mode 100644 index 0000000000000..4e1a4f7aea693 --- /dev/null +++ b/ext/session/tests/bug66827.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #66827: Session raises E_NOTICE when session name variable is array. +--INI-- +--SKIPIF-- + +--FILE-- +