Improved $cookie_ evaluation.
Some checks failed
buildbot / buildbot (push) Has been cancelled

In case "Cookie" header is sent by client, multiple cookie pairs were
incorrectly split by a semicolon and comma.

Now they are split by a semicolon only.

For example, next variables will be found for "Cookie: a=b, c=d; e=f":
- $cookie_a: "b, c=d"
- $cookie_e: "f"

Closes #1042 on GitHub.
This commit is contained in:
Vadim Zhestikov 2025-12-18 16:45:21 -08:00 committed by VadimZhestikov
parent f8e1bc5b98
commit bf0508fabf
4 changed files with 30 additions and 6 deletions

View file

@ -338,8 +338,8 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
ngx_http_set_ctx(r, ctx, ngx_http_userid_filter_module);
}
cookie = ngx_http_parse_multi_header_lines(r, r->headers_in.cookie,
&conf->name, &ctx->cookie);
cookie = ngx_http_parse_cookie_lines(r, r->headers_in.cookie, &conf->name,
&ctx->cookie);
if (cookie == NULL) {
return ctx;
}

View file

@ -110,6 +110,8 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
ngx_uint_t allow_underscores);
ngx_table_elt_t *ngx_http_parse_multi_header_lines(ngx_http_request_t *r,
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value);
ngx_table_elt_t *ngx_http_parse_cookie_lines(ngx_http_request_t *r,
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value);
ngx_table_elt_t *ngx_http_parse_set_cookie_lines(ngx_http_request_t *r,
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value);
ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len,

View file

@ -10,6 +10,10 @@
#include <ngx_http.h>
static ngx_table_elt_t *ngx_http_parse_multi_header_lines_internal(
ngx_http_request_t *r, ngx_table_elt_t *headers, ngx_str_t *name,
ngx_str_t *value, u_char sep);
static uint32_t usual[] = {
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
@ -1997,6 +2001,24 @@ unsafe:
ngx_table_elt_t *
ngx_http_parse_multi_header_lines(ngx_http_request_t *r,
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value)
{
return ngx_http_parse_multi_header_lines_internal(r, headers, name, value,
',');
}
ngx_table_elt_t *
ngx_http_parse_cookie_lines(ngx_http_request_t *r,
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value)
{
return ngx_http_parse_multi_header_lines_internal(r, headers, name, value,
';');
}
static ngx_table_elt_t *
ngx_http_parse_multi_header_lines_internal(ngx_http_request_t *r,
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value, u_char sep)
{
u_char *start, *last, *end, ch;
ngx_table_elt_t *h;
@ -2024,7 +2046,7 @@ ngx_http_parse_multi_header_lines(ngx_http_request_t *r,
}
if (value == NULL) {
if (start == end || *start == ',') {
if (start == end || *start == sep) {
return h;
}
@ -2038,7 +2060,7 @@ ngx_http_parse_multi_header_lines(ngx_http_request_t *r,
while (start < end && *start == ' ') { start++; }
for (last = start; last < end && *last != ';'; last++) {
for (last = start; last < end && *last != sep; last++) {
/* void */
}
@ -2051,7 +2073,7 @@ ngx_http_parse_multi_header_lines(ngx_http_request_t *r,
while (start < end) {
ch = *start++;
if (ch == ';' || ch == ',') {
if (ch == sep) {
break;
}
}

View file

@ -1088,7 +1088,7 @@ ngx_http_variable_cookie(ngx_http_request_t *r, ngx_http_variable_value_t *v,
s.len = name->len - (sizeof("cookie_") - 1);
s.data = name->data + sizeof("cookie_") - 1;
if (ngx_http_parse_multi_header_lines(r, r->headers_in.cookie, &s, &cookie)
if (ngx_http_parse_cookie_lines(r, r->headers_in.cookie, &s, &cookie)
== NULL)
{
v->not_found = 1;