Skip to content

Commit 75b6914

Browse files
authored
Merge pull request #78 from MDA2AV/feature/extra-tests-fix
Add tests, fix results for sequence tests
2 parents e39eed1 + a463768 commit 75b6914

16 files changed

Lines changed: 973 additions & 32 deletions

docs/content/docs/rfc-requirement-dashboard.md

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "RFC Requirement Dashboard"
3-
description: "Complete RFC 2119 requirement-level analysis for all 172 Http11Probe tests"
3+
description: "Complete RFC 2119 requirement-level analysis for all 183 Http11Probe tests"
44
weight: 2
55
breadcrumbs: false
66
---
@@ -11,18 +11,18 @@ This dashboard classifies every Http11Probe test by its [RFC 2119](https://www.r
1111

1212
| Requirement Level | Count | Meaning (RFC 2119) |
1313
|---|---|---|
14-
| **MUST** | 96 | Absolute requirement — no compliant implementation may deviate |
14+
| **MUST** | 103 | Absolute requirement — no compliant implementation may deviate |
1515
| **SHOULD** | 29 | Recommended — valid exceptions exist but must be understood |
1616
| **MAY** | 10 | Truly optional — either behavior is fully compliant |
1717
| **"ought to"** | 1 | Weaker than SHOULD — recommended but not normative |
18-
| **Unscored** | 25 | Informational — no pass/fail judgement |
18+
| **Unscored** | 29 | Informational — no pass/fail judgement |
1919
| **N/A** | 11 | Best-practice / no single RFC verb applies |
2020

21-
**Total: 172 tests**
21+
**Total: 183 tests**
2222

2323
---
2424

25-
## MUST-Level Requirements (96 tests)
25+
## MUST-Level Requirements (103 tests)
2626

2727
These tests enforce absolute RFC requirements. A compliant server has no discretion — it **MUST** behave as specified.
2828

@@ -99,11 +99,18 @@ The RFC requires rejection, but the mechanism (400 status or connection close) h
9999
| 56 | `SMUG-CLTE-KEEPALIVE` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | CL+TE conflict with explicit `Connection: keep-alive`. **MUST** close connection regardless of keep-alive. |
100100
| 57 | `SMUG-CLTE-DESYNC` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Classic CL.TE desync: CL=6 with TE=chunked body `0\r\n\r\nX`. Poison byte after CL boundary confirms desync. **MUST** close connection. |
101101
| 58 | `SMUG-TECL-DESYNC` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Reverse TE.CL desync: TE=chunked terminates at `0\r\n\r\n` but CL=30. Extra bytes on wire confirm desync. **MUST** close connection. |
102+
| 59 | `SMUG-CHUNK-SIZE-PLUS` | Smuggling | [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) | Grammar: `chunk-size = 1*HEXDIG`. Leading `+` is not HEXDIG; invalid chunk framing **MUST** be rejected. |
103+
| 60 | `SMUG-CHUNK-SIZE-TRAILING-OWS` | Smuggling | [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) | Grammar: `chunk-size = 1*HEXDIG`. Trailing whitespace in chunk-size is invalid syntax and **MUST** be rejected. |
104+
| 61 | `SMUG-CHUNK-EXT-INVALID-TOKEN` | Smuggling | [RFC 9112 §7.1.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1.1) | Grammar: `chunk-ext-name = token`. `[` is not a valid token character, so the chunk extension is invalid and **MUST** be rejected. |
105+
| 62 | `SMUG-OPTIONS-TE-OBS-FOLD` | Smuggling | [RFC 9112 §5.2](https://www.rfc-editor.org/rfc/rfc9112#section-5.2) | "A server that receives an obs-fold in a request message ... **MUST** either reject the message by sending a 400 (Bad Request) ... or replace each received obs-fold with one or more SP octets." |
106+
| 63 | `SMUG-CHUNK-INVALID-SIZE-DESYNC` | Smuggling | [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) | Sequence test with invalid `+0` chunk-size plus poison byte. Since `chunk-size = 1*HEXDIG`, this framing error **MUST** be rejected to prevent desync. |
102107
| 54 | `COMP-CONNECTION-CLOSE` | Compliance | [RFC 9112 §9.6](https://www.rfc-editor.org/rfc/rfc9112#section-9.6) | "A server that receives a 'close' connection option **MUST** initiate closure of the connection after it sends the final response to the request that contained the 'close' connection option." |
103108
| 55 | `COMP-OPTIONS-STAR` | Compliance | [RFC 9112 §3.2.4](https://www.rfc-editor.org/rfc/rfc9112#section-3.2.4) | The asterisk-form `*` is defined only for OPTIONS. A valid OPTIONS * request **MUST** be accepted. |
104109
| 56 | `COMP-POST-CL-BODY` | Compliance | [RFC 9112 §6.2](https://www.rfc-editor.org/rfc/rfc9112#section-6.2) | "If a valid Content-Length header field is present without Transfer-Encoding, its decimal value defines the expected message body length in octets." Server **MUST** accept a well-formed POST with matching body. |
105110
| 57 | `COMP-POST-CL-ZERO` | Compliance | [RFC 9112 §6.2](https://www.rfc-editor.org/rfc/rfc9112#section-6.2) | Content-Length: 0 is a valid 1*DIGIT value. Server **MUST** accept zero-length body. |
106111
| 58 | `COMP-POST-NO-CL-NO-TE` | Compliance | [RFC 9112 §6.3](https://www.rfc-editor.org/rfc/rfc9112#section-6.3) | "If this is a request message and none of the above are true, then the message body length is zero (no message body is present)." Server **MUST** treat as zero-length. |
112+
| 59 | `COMP-RANGE-POST` | Compliance | [RFC 9110 §14.2](https://www.rfc-editor.org/rfc/rfc9110#section-14.2) | "A server **MUST** ignore a Range header field received with a request method other than GET." |
113+
| 60 | `COMP-UPGRADE-HTTP10` | Compliance | [RFC 9110 §7.8](https://www.rfc-editor.org/rfc/rfc9110#section-7.8) | "A server **MUST** ignore an Upgrade header field that is received in an HTTP/1.0 request." |
107114
| 59 | `COMP-CHUNKED-BODY` | Compliance | [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) | "A recipient **MUST** be able to parse and decode the chunked transfer coding." |
108115
| 60 | `COMP-CHUNKED-MULTI` | Compliance | [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) | Same — multi-chunk is the standard chunked format. **MUST** accept. |
109116
| 61 | `COMP-CHUNKED-EMPTY` | Compliance | [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) | A zero-length chunked body (just `0\r\n\r\n`) is valid. **MUST** accept. |
@@ -205,7 +212,7 @@ Weaker than SHOULD — recommends but does not normatively require.
205212

206213
---
207214

208-
## Unscored Tests (25 tests)
215+
## Unscored Tests (29 tests)
209216

210217
These tests are informational — they produce warnings but never fail.
211218

@@ -236,6 +243,10 @@ These tests are informational — they produce warnings but never fail.
236243
| 23 | `COMP-RANGE-INVALID` | Compliance | [RFC 9110 §14.2](https://www.rfc-editor.org/rfc/rfc9110#section-14.2) | "A server **MAY** ignore the Range header field." Invalid Range syntax — 2xx or 416 both acceptable. |
237244
| 24 | `COMP-POST-UNSUPPORTED-CT` | Compliance | [RFC 9110 §15.5.16](https://www.rfc-editor.org/rfc/rfc9110#section-15.5.16) | POST with unknown Content-Type — 415 or 2xx both acceptable. |
238245
| 25 | `SMUG-PIPELINE-SAFE` | Smuggling | [RFC 9112 §9.3](https://www.rfc-editor.org/rfc/rfc9112#section-9.3) | Baseline: two clean pipelined GETs. Validates sequence test infrastructure against the target. |
246+
| 26 | `SMUG-CL0-BODY-POISON` | Smuggling | [RFC 9112 §6.2](https://www.rfc-editor.org/rfc/rfc9112#section-6.2) | `Content-Length: 0` plus trailing bytes, then follow-up GET on same socket. Sequence telemetry for `0.CL`-style poisoning behavior. |
247+
| 27 | `SMUG-GET-CL-BODY-DESYNC` | Smuggling | [RFC 9110 §9.3.1](https://www.rfc-editor.org/rfc/rfc9110#section-9.3.1) | "Content received in a GET request ... might lead some implementations to reject the request and close the connection because of its potential as a request smuggling attack." Adds follow-up desync check. |
248+
| 28 | `SMUG-OPTIONS-CL-BODY-DESYNC` | Smuggling | [RFC 9110 §9.3.7](https://www.rfc-editor.org/rfc/rfc9110#section-9.3.7) | OPTIONS with body plus follow-up GET to detect unread-body poisoning on persistent connections. |
249+
| 29 | `SMUG-EXPECT-100-CL-DESYNC` | Smuggling | [RFC 9110 §10.1.1](https://www.rfc-editor.org/rfc/rfc9110#section-10.1.1) | Expect/continue flow with immediate body plus follow-up GET; highlights whether connection framing remains synchronized. |
239250

240251
---
241252

@@ -261,25 +272,25 @@ These tests don't map to a single RFC 2119 keyword but enforce defensive best pr
261272

262273
## Requirement Level by Suite
263274

264-
### Compliance Suite (74 tests)
275+
### Compliance Suite (76 tests)
265276

266277
| Level | Tests |
267278
|-------|-------|
268-
| MUST | 45 |
279+
| MUST | 47 |
269280
| SHOULD | 15 |
270281
| MAY | 6 |
271282
| Unscored | 7 |
272283
| N/A | 1 |
273284

274-
### Smuggling Suite (67 tests)
285+
### Smuggling Suite (76 tests)
275286

276287
| Level | Tests |
277288
|-------|-------|
278-
| MUST | 39 |
289+
| MUST | 44 |
279290
| SHOULD | 9 |
280291
| MAY | 3 |
281292
| "ought to" | 1 |
282-
| Unscored | 15 |
293+
| Unscored | 19 |
283294

284295
### Malformed Input Suite (26 tests)
285296

@@ -310,26 +321,26 @@ These tests don't map to a single RFC 2119 keyword but enforce defensive best pr
310321
| RFC 9112 §3 | 9 | Request line, method, request-target |
311322
| RFC 9112 §3.2 | 11 | Host header, request-target forms |
312323
| RFC 9112 §5 | 7 | Header field syntax, sp-before-colon |
313-
| RFC 9112 §5.2 | 2 | Obsolete line folding |
324+
| RFC 9112 §5.2 | 3 | Obsolete line folding |
314325
| RFC 9112 §6.1 | 21 | Transfer-Encoding, CL+TE ambiguity |
315-
| RFC 9112 §6.2 | 4 | Content-Length body framing |
326+
| RFC 9112 §6.2 | 5 | Content-Length body framing |
316327
| RFC 9112 §6.3 | 5 | Message body length determination |
317-
| RFC 9112 §7.1 | 15 | Chunked transfer coding format |
318-
| RFC 9112 §7.1.1 | 4 | Chunk extensions |
328+
| RFC 9112 §7.1 | 18 | Chunked transfer coding format |
329+
| RFC 9112 §7.1.1 | 5 | Chunk extensions |
319330
| RFC 9112 §7.1.2 | 1 | Chunked trailer section |
320331
| RFC 9112 §9.3-9.6 | 3 | Connection management |
321332
| RFC 9110 §5.3 | 1 | Header field duplication |
322333
| RFC 9110 §5.4-5.6 | 8 | Field limits, values, lists, tokens |
323334
| RFC 9110 §6.6.1 | 1 | Date header |
324335
| RFC 9110 §7.2 | 1 | Host header semantics |
325-
| RFC 9110 §7.8 | 4 | Upgrade |
336+
| RFC 9110 §7.8 | 5 | Upgrade |
326337
| RFC 9110 §8.3 | 1 | Content-Type |
327338
| RFC 9110 §8.6 | 14 | Content-Length semantics |
328-
| RFC 9110 §9.1-9.3 | 10 | Methods (GET, HEAD, CONNECT, OPTIONS, TRACE) |
329-
| RFC 9110 §10.1.1 | 2 | Expect header |
339+
| RFC 9110 §9.1-9.3 | 12 | Methods (GET, HEAD, CONNECT, OPTIONS, TRACE) |
340+
| RFC 9110 §10.1.1 | 3 | Expect header |
330341
| RFC 9110 §6.5 | 5 | Trailer field restrictions |
331342
| RFC 9110 §12.5.1 | 1 | Content negotiation (Accept) |
332-
| RFC 9110 §14.2 | 2 | Range requests |
343+
| RFC 9110 §14.2 | 3 | Range requests |
333344
| RFC 9110 §15.2 | 1 | 1xx status codes |
334345
| RFC 9110 §15.5.6 | 1 | 405 Method Not Allowed |
335346
| RFC 9110 §15.5.16 | 1 | 415 Unsupported Media Type |

docs/content/docs/smuggling/_index.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,23 @@ For these, `400` is the strict/safe response and `2xx` is RFC-compliant. Http11P
7272
{{< card link="te-not-final-chunked" title="TE-NOT-FINAL-CHUNKED" subtitle="Chunked is not the final transfer encoding." >}}
7373
{{< card link="te-http10" title="TE-HTTP10" subtitle="Transfer-Encoding in HTTP/1.0 request." >}}
7474
{{< card link="chunk-bare-semicolon" title="CHUNK-BARE-SEMICOLON" subtitle="Bare semicolon in chunk size." >}}
75+
{{< card link="chunk-ext-invalid-token" title="CHUNK-EXT-INVALID-TOKEN" subtitle="Invalid token character in chunk extension name." >}}
7576
{{< card link="bare-cr-header-value" title="BARE-CR-HEADER-VALUE" subtitle="Bare CR in header value." >}}
7677
{{< card link="cl-octal" title="CL-OCTAL" subtitle="Content-Length with octal prefix." >}}
7778
{{< card link="chunk-underscore" title="CHUNK-UNDERSCORE" subtitle="Underscore in chunk size." >}}
7879
{{< card link="te-empty-value" title="TE-EMPTY-VALUE" subtitle="Empty Transfer-Encoding value with CL." >}}
7980
{{< card link="te-leading-comma" title="TE-LEADING-COMMA" subtitle="Leading comma in Transfer-Encoding." >}}
8081
{{< card link="te-duplicate-headers" title="TE-DUPLICATE-HEADERS" subtitle="Two TE headers with conflicting values." >}}
8182
{{< card link="chunk-hex-prefix" title="CHUNK-HEX-PREFIX" subtitle="Chunk size with 0x prefix." >}}
83+
{{< card link="chunk-size-plus" title="CHUNK-SIZE-PLUS" subtitle="Chunk size with leading plus sign." >}}
84+
{{< card link="chunk-size-trailing-ows" title="CHUNK-SIZE-TRAILING-OWS" subtitle="Chunk size with trailing whitespace." >}}
8285
{{< card link="cl-hex-prefix" title="CL-HEX-PREFIX" subtitle="Content-Length with 0x prefix." >}}
8386
{{< card link="cl-internal-space" title="CL-INTERNAL-SPACE" subtitle="Space inside Content-Length value." >}}
8487
{{< card link="chunk-leading-sp" title="CHUNK-LEADING-SP" subtitle="Leading space in chunk size." >}}
8588
{{< card link="chunk-missing-trailing-crlf" title="CHUNK-MISSING-TRAILING-CRLF" subtitle="Chunk data without trailing CRLF." >}}
8689
{{< card link="chunk-ext-lf" title="CHUNK-EXT-LF" subtitle="Bare LF in chunk extension (TERM.EXT vector)." >}}
8790
{{< card link="chunk-spill" title="CHUNK-SPILL" subtitle="Chunk declares size 5 but sends 7 bytes." >}}
91+
{{< card link="chunk-invalid-size-desync" title="CHUNK-INVALID-SIZE-DESYNC" subtitle="Invalid chunk size plus poison-byte follow-up check." >}}
8892
{{< card link="chunk-lf-term" title="CHUNK-LF-TERM" subtitle="Bare LF as chunk data terminator." >}}
8993
{{< card link="chunk-ext-ctrl" title="CHUNK-EXT-CTRL" subtitle="NUL byte in chunk extension." >}}
9094
{{< card link="chunk-ext-cr" title="CHUNK-EXT-CR" subtitle="Bare CR inside chunk extension metadata." >}}
@@ -100,6 +104,7 @@ For these, `400` is the strict/safe response and `2xx` is RFC-compliant. Http11P
100104
{{< card link="cl-double-zero" title="CL-DOUBLE-ZERO" subtitle="Content-Length: 00 — leading zero ambiguity." >}}
101105
{{< card link="cl-leading-zeros-octal" title="CL-LEADING-ZEROS-OCTAL" subtitle="Content-Length: 0200 — octal vs decimal disagreement." >}}
102106
{{< card link="te-obs-fold" title="TE-OBS-FOLD" subtitle="Transfer-Encoding with obs-fold line wrapping." >}}
107+
{{< card link="options-te-obs-fold" title="OPTIONS-TE-OBS-FOLD" subtitle="OPTIONS path for TE obs-fold plus follow-up close check." >}}
103108
{{< card link="te-trailing-comma" title="TE-TRAILING-COMMA" subtitle="Transfer-Encoding: chunked, — trailing comma." >}}
104109
{{< card link="multiple-host-comma" title="MULTIPLE-HOST-COMMA" subtitle="Host with comma-separated values." >}}
105110
{{< /cards >}}
@@ -116,13 +121,17 @@ For these, `400` is the strict/safe response and `2xx` is RFC-compliant. Http11P
116121
{{< card link="cl-comma-triple" title="CL-COMMA-TRIPLE" subtitle="Three comma-separated identical CL values." >}}
117122
{{< card link="chunked-with-params" title="CHUNKED-WITH-PARAMS" subtitle="Parameters on chunked encoding." >}}
118123
{{< card link="expect-100-cl" title="EXPECT-100-CL" subtitle="Expect: 100-continue with Content-Length." >}}
124+
{{< card link="expect-100-cl-desync" title="EXPECT-100-CL-DESYNC" subtitle="Expect workflow with follow-up desync check." >}}
119125
{{< card link="trailer-cl" title="TRAILER-CL" subtitle="Content-Length in chunked trailers (prohibited)." >}}
120126
{{< card link="trailer-te" title="TRAILER-TE" subtitle="Transfer-Encoding in chunked trailers (prohibited)." >}}
121127
{{< card link="trailer-host" title="TRAILER-HOST" subtitle="Host header in chunked trailers (must not route)." >}}
122128
{{< card link="trailer-auth" title="TRAILER-AUTH" subtitle="Authorization in chunked trailers (prohibited)." >}}
123129
{{< card link="trailer-content-type" title="TRAILER-CONTENT-TYPE" subtitle="Content-Type in chunked trailers (prohibited)." >}}
130+
{{< card link="cl0-body-poison" title="CL0-BODY-POISON" subtitle="CL:0 with trailing byte and follow-up request." >}}
131+
{{< card link="get-cl-body-desync" title="GET-CL-BODY-DESYNC" subtitle="GET with body plus follow-up desync check." >}}
124132
{{< card link="head-cl-body" title="HEAD-CL-BODY" subtitle="HEAD with Content-Length and body." >}}
125133
{{< card link="options-cl-body" title="OPTIONS-CL-BODY" subtitle="OPTIONS with Content-Length and body." >}}
134+
{{< card link="options-cl-body-desync" title="OPTIONS-CL-BODY-DESYNC" subtitle="OPTIONS with body plus follow-up desync check." >}}
126135
{{< card link="te-tab-before-value" title="TE-TAB-BEFORE-VALUE" subtitle="Tab as OWS before Transfer-Encoding value." >}}
127136
{{< card link="absolute-uri-host-mismatch" title="ABSOLUTE-URI-HOST-MISMATCH" subtitle="Absolute-form URI with different Host header." >}}
128137
{{< /cards >}}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
title: "CHUNK-EXT-INVALID-TOKEN"
3+
description: "SMUG-CHUNK-EXT-INVALID-TOKEN test documentation"
4+
weight: 1
5+
---
6+
7+
| | |
8+
|---|---|
9+
| **Test ID** | `SMUG-CHUNK-EXT-INVALID-TOKEN` |
10+
| **Category** | Smuggling |
11+
| **RFC** | [RFC 9112 §7.1.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1.1) |
12+
| **Requirement** | Implicit MUST (grammar violation) |
13+
| **Expected** | `400` or close |
14+
15+
## What it sends
16+
17+
A chunk extension with an invalid token character in the extension name (`bad[`):
18+
19+
```http
20+
POST / HTTP/1.1\r\n
21+
Host: localhost:8080\r\n
22+
Transfer-Encoding: chunked\r\n
23+
\r\n
24+
5;bad[=x\r\n
25+
hello\r\n
26+
0\r\n
27+
\r\n
28+
```
29+
30+
## What the RFC says
31+
32+
> "chunk-ext-name = token" -- RFC 9112 Section 7.1.1
33+
34+
`[` is not a valid token character, so the extension syntax is invalid.
35+
36+
## Partial Coverage Note
37+
38+
Existing tests already cover malformed chunk extensions (`SMUG-CHUNK-BARE-SEMICOLON`, `SMUG-CHUNK-EXT-CTRL`, `SMUG-CHUNK-EXT-CR`, `SMUG-CHUNK-EXT-LF`). This case specifically targets invalid token characters in extension names.
39+
40+
## Why it matters
41+
42+
Different extension parsers may tokenize this differently, creating front-end/back-end framing inconsistencies.
43+
44+
## Sources
45+
46+
- [RFC 9112 §7.1.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1.1)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
title: "CHUNK-INVALID-SIZE-DESYNC"
3+
description: "SMUG-CHUNK-INVALID-SIZE-DESYNC test documentation"
4+
weight: 1
5+
---
6+
7+
| | |
8+
|---|---|
9+
| **Test ID** | `SMUG-CHUNK-INVALID-SIZE-DESYNC` |
10+
| **Category** | Smuggling |
11+
| **RFC** | [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) |
12+
| **Requirement** | MUST |
13+
| **Expected** | `400` or close |
14+
15+
## What it sends
16+
17+
A two-step sequence: invalid chunk-size `+0` with poison byte `X`, then a clean `GET`.
18+
19+
```http
20+
POST / HTTP/1.1\r\n
21+
Host: localhost:8080\r\n
22+
Transfer-Encoding: chunked\r\n
23+
\r\n
24+
+0\r\n
25+
\r\n
26+
X
27+
28+
GET / HTTP/1.1\r\n
29+
Host: localhost:8080\r\n
30+
\r\n
31+
```
32+
33+
## What the RFC says
34+
35+
> "chunk-size = 1*HEXDIG" -- RFC 9112 Section 7.1
36+
37+
Invalid chunk-size is a framing error. This sequence confirms whether acceptance leads to follow-up parsing corruption.
38+
39+
## Partial Coverage Note
40+
41+
Existing tests (`SMUG-CHUNK-NEGATIVE`, `SMUG-CHUNK-HEX-PREFIX`, `SMUG-CHUNK-SPILL`, `MAL-CHUNK-SIZE-OVERFLOW`) cover invalid chunk primitives. This test adds explicit desync confirmation via a follow-up request.
42+
43+
## Why it matters
44+
45+
If invalid chunk-size is tolerated and the connection remains open, poison bytes can be interpreted as the next request.
46+
47+
## Sources
48+
49+
- [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
title: "CHUNK-SIZE-PLUS"
3+
description: "SMUG-CHUNK-SIZE-PLUS test documentation"
4+
weight: 1
5+
---
6+
7+
| | |
8+
|---|---|
9+
| **Test ID** | `SMUG-CHUNK-SIZE-PLUS` |
10+
| **Category** | Smuggling |
11+
| **RFC** | [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) |
12+
| **Requirement** | Implicit MUST (grammar violation) |
13+
| **Expected** | `400` or close |
14+
15+
## What it sends
16+
17+
A chunked request where chunk-size is prefixed by `+`.
18+
19+
```http
20+
POST / HTTP/1.1\r\n
21+
Host: localhost:8080\r\n
22+
Transfer-Encoding: chunked\r\n
23+
\r\n
24+
+5\r\n
25+
hello\r\n
26+
0\r\n
27+
\r\n
28+
```
29+
30+
## What the RFC says
31+
32+
> "chunk-size = 1*HEXDIG" -- RFC 9112 Section 7.1
33+
34+
The plus sign is not a hexadecimal digit. The chunk-size token is invalid.
35+
36+
## Why it matters
37+
38+
Lenient numeric parsing (`+5`) in one component and strict parsing in another creates parser disagreement and desync opportunities.
39+
40+
## Sources
41+
42+
- [RFC 9112 §7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1)

0 commit comments

Comments
 (0)