diff src/http/ngx_http_parse.c @ 9242:ddcedfa3a809

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.
author Maxim Dounin <mdounin@mdounin.ru>
date Sat, 30 Mar 2024 05:10:40 +0300
parents f3df785649ae
children 9a5e2296c1be
line wrap: on
line diff
--- 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;