[PATCH 10 of 10] HTTP: just one empty line now accepted when parsing request line
Maxim Dounin
mdounin at mdounin.ru
Fri Mar 15 18:14:24 UTC 2024
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1710526261 -10800
# Fri Mar 15 21:11:01 2024 +0300
# Node ID 3c67054eeb098757aaf59a45b3dcf38228a1552b
# Parent 9580cb3029058154973dd7b28c9da709c5bc3e31
HTTP: just one empty line now accepted when parsing request line.
This ensures that multiple CRLFs cannot be used as a DoS vector, and also
in line with RFC 9112 ("SHOULD ignore at least one empty line"). Further,
bare CRs are no longer accepted.
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -106,6 +106,8 @@ ngx_http_parse_request_line(ngx_http_req
u_char c, ch, *p, *m;
enum {
sw_start = 0,
+ sw_newline,
+ sw_method_start,
sw_method,
sw_spaces_before_uri,
sw_schema,
@@ -143,7 +145,13 @@ ngx_http_parse_request_line(ngx_http_req
case sw_start:
r->request_start = p;
- if (ch == CR || ch == LF) {
+ if (ch == CR) {
+ state = sw_newline;
+ break;
+ }
+
+ if (ch == LF) {
+ state = sw_method_start;
break;
}
@@ -154,6 +162,25 @@ ngx_http_parse_request_line(ngx_http_req
state = sw_method;
break;
+ case sw_newline:
+
+ if (ch == LF) {
+ state = sw_method_start;
+ break;
+ }
+
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
+
+ case sw_method_start:
+ r->request_start = p;
+
+ if ((ch < 'A' || ch > 'Z') && ch != '_' && ch != '-') {
+ return NGX_HTTP_PARSE_INVALID_METHOD;
+ }
+
+ state = sw_method;
+ break;
+
case sw_method:
if (ch == ' ') {
r->method_end = p - 1;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1623,16 +1623,6 @@ ngx_http_alloc_large_header_buffer(ngx_h
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http alloc large header buffer");
- if (request_line && r->state == 0) {
-
- /* the client fills up the buffer with "\r\n" */
-
- r->header_in->pos = r->header_in->start;
- r->header_in->last = r->header_in->start;
-
- return NGX_OK;
- }
-
old = request_line ? r->request_start : r->header_name_start;
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
More information about the nginx-devel
mailing list