From 2dbda125db743f71d4dd104b29fa58620eb49de2 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Mon, 30 Sep 2019 19:11:17 +0300 Subject: HTTP parser: normalization of paths ending with "." or "..". Earlier, the paths were normalized only if there was a "/" at the end, which is wrong according to section 5.2.4 of RFC 3986 and hypothetically may allow to the directory above the document root. --- src/nxt_http_parse.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 5b009d96..63fd5130 100644 --- a/src/nxt_http_parse.c +++ b/src/nxt_http_parse.c @@ -970,9 +970,11 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) state = sw_quoted; continue; case '?': + u--; args = p; goto args; case '#': + u--; goto done; default: state = sw_normal; @@ -991,30 +993,42 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) } switch (ch) { + case '/': - state = sw_slash; + case '?': + case '#': u -= 5; + for ( ;; ) { if (u < rp->path.start) { return NXT_HTTP_PARSE_INVALID; } + if (*u == '/') { u++; break; } + u--; } + + if (ch == '?') { + args = p; + goto args; + } + + if (ch == '#') { + goto done; + } + + state = sw_slash; break; case '%': saved_state = state; state = sw_quoted; continue; - case '?': - args = p; - goto args; - case '#': - goto done; + default: state = sw_normal; *u++ = ch; @@ -1097,8 +1111,14 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) } } - if (state >= sw_quoted) { - return NXT_HTTP_PARSE_INVALID; + if (state >= sw_dot) { + if (state >= sw_quoted) { + return NXT_HTTP_PARSE_INVALID; + } + + /* "/." and "/.." must be normalized similar to "/./" and "/../". */ + ch = '/'; + goto again; } args: -- cgit