Skip to content

Commit 12c26d8

Browse files
authored
Merge pull request #85 from MDA2AV/feature/add-tests-sequence
Add more sequence tests
2 parents 2a3e1c6 + f44286d commit 12c26d8

27 files changed

Lines changed: 2125 additions & 192 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,7 @@ package-lock.json
7676

7777
# Probe results (local testing)
7878
probe-*.json
79+
80+
# Probe action outputs (local script)
81+
probe-data.js
82+
probe-comment.md

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

Lines changed: 31 additions & 20 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 183 Http11Probe tests"
3+
description: "Complete RFC 2119 requirement-level analysis for all 194 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** | 103 | Absolute requirement — no compliant implementation may deviate |
14+
| **MUST** | 113 | 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** | 29 | Informational — no pass/fail judgement |
18+
| **Unscored** | 30 | Informational — no pass/fail judgement |
1919
| **N/A** | 11 | Best-practice / no single RFC verb applies |
2020

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

2323
---
2424

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

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

@@ -96,14 +96,14 @@ The RFC requires rejection, but the mechanism (400 status or connection close) h
9696
| 53 | `SMUG-TE-XCHUNKED` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Unknown TE with CL present: "Regardless, the server **MUST** close the connection after responding to such a request." Combined with §6.1: "A server that receives a request message with a transfer coding it does not understand **SHOULD** respond with 501." |
9797
| 54 | `SMUG-CLTE-CONN-CLOSE` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Sequence test: CL+TE combined, then follow-up GET on same socket. "The server **MUST** close the connection after responding to such a request." If follow-up receives a response, MUST-close violated. |
9898
| 55 | `SMUG-TECL-CONN-CLOSE` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Same as CLTE-CONN-CLOSE with TE before CL header order. **MUST** close connection. |
99-
| 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. |
10099
| 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. |
101-
| 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. |
100+
| 58 | `SMUG-CLTE-SMUGGLED-GET` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | CL.TE desync payload where the trailing bytes form a full `GET /` request. If the server returns multiple HTTP responses on one send, the embedded request was executed. "Regardless, the server **MUST** close the connection after responding to such a request." |
101+
| 59 | `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+
| 60 | `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+
| 61 | `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+
| 62 | `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+
| 63 | `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+
| 64 | `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. |
107107
| 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." |
108108
| 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. |
109109
| 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. |
@@ -142,6 +142,16 @@ The RFC requires rejection, but the mechanism (400 status or connection close) h
142142
| 87 | `COMP-DATE-HEADER` | Compliance | [RFC 9110 §6.6.1](https://www.rfc-editor.org/rfc/rfc9110#section-6.6.1) | "An origin server with a clock **MUST** generate a Date header field in all 2xx (Successful), 3xx (Redirection), and 4xx (Client Error) responses." |
143143
| 88 | `COMP-NO-1XX-HTTP10` | Compliance | [RFC 9110 §15.2](https://www.rfc-editor.org/rfc/rfc9110#section-15.2) | "Since HTTP/1.0 did not define any 1xx status codes, a server **MUST NOT** send a 1xx response to an HTTP/1.0 client." |
144144
| 89 | `COMP-NO-CL-IN-204` | Compliance | [RFC 9110 §8.6](https://www.rfc-editor.org/rfc/rfc9110#section-8.6) | "A server **MUST NOT** send a Content-Length header field in any response with a status code of 1xx (Informational) or 204 (No Content)." |
145+
| 90 | `SMUG-CLTE-SMUGGLED-GET-CL-PLUS` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Variant of `SMUG-CLTE-SMUGGLED-GET` with `Content-Length: +N` (malformed CL) and `Transfer-Encoding: chunked`, embedding a full `GET /` in the body. "Regardless, the server **MUST** close the connection after responding to such a request." |
146+
| 91 | `SMUG-CLTE-SMUGGLED-GET-CL-NON-NUMERIC` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Variant of `SMUG-CLTE-SMUGGLED-GET` with `Content-Length: N<alpha>` (non-numeric suffix) and `Transfer-Encoding: chunked`, embedding a full `GET /` in the body. "Regardless, the server **MUST** close the connection after responding to such a request." |
147+
| 92 | `SMUG-CLTE-SMUGGLED-GET-TE-OBS-FOLD` | Smuggling | [RFC 9112 §5.2](https://www.rfc-editor.org/rfc/rfc9112#section-5.2) | Variant of `SMUG-CLTE-SMUGGLED-GET` with obs-folded `Transfer-Encoding:\r\n chunked` plus `Content-Length`, embedding a full `GET /` in the body. "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 prior to interpreting the field value..." |
148+
| 93 | `SMUG-CLTE-SMUGGLED-HEAD` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Embedded-request confirmation variant using a smuggled `HEAD /` request. "Regardless, the server **MUST** close the connection after responding to such a request." |
149+
| 94 | `SMUG-CLTE-SMUGGLED-GET-TE-TRAILING-SPACE` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Variant of `SMUG-CLTE-SMUGGLED-GET` with `Transfer-Encoding: chunked␠` (trailing space) plus `Content-Length`. "Regardless, the server **MUST** close the connection after responding to such a request." |
150+
| 95 | `SMUG-CLTE-SMUGGLED-GET-TE-LEADING-COMMA` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Variant of `SMUG-CLTE-SMUGGLED-GET` with `Transfer-Encoding: , chunked` plus `Content-Length`. "Regardless, the server **MUST** close the connection after responding to such a request." |
151+
| 96 | `SMUG-CLTE-SMUGGLED-GET-TE-CASE-MISMATCH` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Variant of `SMUG-CLTE-SMUGGLED-GET` with `Transfer-Encoding: Chunked` (case mismatch) plus `Content-Length`. "Regardless, the server **MUST** close the connection after responding to such a request." |
152+
| 97 | `SMUG-TE-DUPLICATE-HEADERS-SMUGGLED-GET` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | Sequence confirmation variant using duplicate `Transfer-Encoding` header fields (`chunked` + `identity`) plus `Content-Length`, embedding a full `GET /` in the body. "Regardless, the server **MUST** close the connection after responding to such a request." |
153+
| 98 | `SMUG-TECL-SMUGGLED-GET` | Smuggling | [RFC 9112 §6.1](https://www.rfc-editor.org/rfc/rfc9112#section-6.1) | TE.CL confirmation using a chunk-size prefix trick: `Content-Length` covers only the chunk-size line, leaving chunk-data that begins with a `GET /` request. "Regardless, the server **MUST** close the connection after responding to such a request." |
154+
| 99 | `SMUG-DUPLICATE-CL-SMUGGLED-GET` | Smuggling | [RFC 9110 §8.6](https://www.rfc-editor.org/rfc/rfc9110#section-8.6) | Sequence confirmation variant of duplicate `Content-Length` using an embedded `GET /` immediately after the shorter body's boundary. "If a message is received without Transfer-Encoding and with an invalid Content-Length header field... the recipient **MUST** treat it as an unrecoverable error." |
145155

146156
---
147157

@@ -212,7 +222,7 @@ Weaker than SHOULD — recommends but does not normatively require.
212222

213223
---
214224

215-
## Unscored Tests (29 tests)
225+
## Unscored Tests (30 tests)
216226

217227
These tests are informational — they produce warnings but never fail.
218228

@@ -247,6 +257,7 @@ These tests are informational — they produce warnings but never fail.
247257
| 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. |
248258
| 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. |
249259
| 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. |
260+
| 30 | `SMUG-GET-CL-PREFIX-DESYNC` | Smuggling | [RFC 9110 §9.3.1](https://www.rfc-editor.org/rfc/rfc9110#section-9.3.1) | GET with a body containing an incomplete request prefix (missing the blank line). The follow-up write completes it and then sends a normal GET. If multiple responses are observed on step 2, the prefix bytes were likely left unread and executed. |
250261

251262
---
252263

@@ -282,15 +293,15 @@ These tests don't map to a single RFC 2119 keyword but enforce defensive best pr
282293
| Unscored | 7 |
283294
| N/A | 1 |
284295

285-
### Smuggling Suite (76 tests)
296+
### Smuggling Suite (87 tests)
286297

287298
| Level | Tests |
288299
|-------|-------|
289-
| MUST | 44 |
300+
| MUST | 54 |
290301
| SHOULD | 9 |
291302
| MAY | 3 |
292303
| "ought to" | 1 |
293-
| Unscored | 19 |
304+
| Unscored | 20 |
294305

295306
### Malformed Input Suite (26 tests)
296307

@@ -321,8 +332,8 @@ These tests don't map to a single RFC 2119 keyword but enforce defensive best pr
321332
| RFC 9112 §3 | 9 | Request line, method, request-target |
322333
| RFC 9112 §3.2 | 11 | Host header, request-target forms |
323334
| RFC 9112 §5 | 7 | Header field syntax, sp-before-colon |
324-
| RFC 9112 §5.2 | 3 | Obsolete line folding |
325-
| RFC 9112 §6.1 | 21 | Transfer-Encoding, CL+TE ambiguity |
335+
| RFC 9112 §5.2 | 4 | Obsolete line folding |
336+
| RFC 9112 §6.1 | 29 | Transfer-Encoding, CL+TE ambiguity |
326337
| RFC 9112 §6.2 | 5 | Content-Length body framing |
327338
| RFC 9112 §6.3 | 5 | Message body length determination |
328339
| RFC 9112 §7.1 | 18 | Chunked transfer coding format |
@@ -335,8 +346,8 @@ These tests don't map to a single RFC 2119 keyword but enforce defensive best pr
335346
| RFC 9110 §7.2 | 1 | Host header semantics |
336347
| RFC 9110 §7.8 | 5 | Upgrade |
337348
| RFC 9110 §8.3 | 1 | Content-Type |
338-
| RFC 9110 §8.6 | 14 | Content-Length semantics |
339-
| RFC 9110 §9.1-9.3 | 12 | Methods (GET, HEAD, CONNECT, OPTIONS, TRACE) |
349+
| RFC 9110 §8.6 | 15 | Content-Length semantics |
350+
| RFC 9110 §9.1-9.3 | 13 | Methods (GET, HEAD, CONNECT, OPTIONS, TRACE) |
340351
| RFC 9110 §10.1.1 | 3 | Expect header |
341352
| RFC 9110 §6.5 | 5 | Trailer field restrictions |
342353
| RFC 9110 §12.5.1 | 1 | Content negotiation (Accept) |

0 commit comments

Comments
 (0)