]> git.kaiwu.me - haproxy.git/commitdiff
MEDIUM: h1/violations: restrict valid version strings to "1.0" and "1.1"
authorWilly Tarreau <w@1wt.eu>
Thu, 5 Nov 2026 17:14:02 +0000 (18:14 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 6 Nov 2026 09:55:54 +0000 (10:55 +0100)
The "invalid-version-string" HTTP violation only permitted to use
versions which are not made of exactly one digit, a dot, and one digit.
But the only versions where such a version is advertised are 1.0 and
1.1, and after them no other version is advertised. This means that the
only valid tokens are exactly 1.0 and 1.1. There's no point in accepting
"0.9", "1.2" nor "2.0" for example, and while haproxy handles them
carefully, some components only look at the second digit, or apply "&1"
to it resulting in 1.2 becoming 1.0 etc. Better be strict on this and
block these ones unless the violation is explicitly accepted. No
visible effect is expected given that the vast majority of servers and
proxies already do not accept other versions.

doc/configuration.txt
src/h1_htx.c

index bcfd439ec822494be8c7d684b7dbc911ef30c08a..1c10ef62ad87b170078cc2f2ea2ccd57f0bfcb97 100644 (file)
@@ -2271,11 +2271,14 @@ acceptable-http-response-violations { [-+]<http-violation>[,...] }
       originating from untrusted clients.
 
     - "invalid-version-string" (both): this controls the acceptance of an HTTP
-      version that is not strictly made of one digit, a dot, and another digit.
-      It should not be needed but might help to work around scripts emittng a
-      version based on an improperly rounded floating point number, such as
-      "HTTP/1.099999875" or "HTTP/0.9999999". This should never be needed, but
-      the risk is low (the string is rebuilt on output).
+      version received on an HTTP/1 connection that is not strictly "1.0" or
+      "1.1". The standard says a version is made of one digit, a dot, and
+      another digit, and since no versions strings other than "1.0" and "1.1"
+      have been standardized. It should not be needed but might help to work
+      around scripts emittng a version based on an improperly rounded floating
+      point number, such as "HTTP/1.2", "HTTP/1.099999875" or "HTTP/0.9999999".
+      This should never be needed, but the risk is low (the string is rebuilt
+      on output).
 
     - "invalid-websocket-key" (both): this controls the acceptance of WebSocket
       protocol Upgrade requests lacking a valid "sec-websocket-key" header, or
index 33bea0e7b7c699e11f5bbb0d77628341f8d191bc..ae848a54f086a10d3a3530e2be73ace46a164841 100644 (file)
@@ -59,9 +59,9 @@ static int h1_process_req_vsn(struct h1m *h1m, union h1_sl *sl)
                        return 0;
 
                if (!istnmatch(sl->rq.v, ist("HTTP/"), 5) ||
-                   !isdigit((unsigned char)*(sl->rq.v.ptr + 5)) ||
+                   *(sl->rq.v.ptr + 5) != '1' ||
                    *(sl->rq.v.ptr + 6) != '.' ||
-                   !isdigit((unsigned char)*(sl->rq.v.ptr + 7)))
+                   (*(sl->rq.v.ptr + 7) & ~1) != '0') // 1.0 or 1.1 exclusively
                        return 0;
        }
        else if (!sl->rq.v.len) {