Skip to content

Commit f7f7d5e

Browse files
authored
Merge pull request #55 from MDA2AV/tests/adding-new-tests
Adding 9 new tests - 8 Compliance, 1 Smuggling
2 parents 07ef363 + 44552cc commit f7f7d5e

21 files changed

Lines changed: 649 additions & 33 deletions

AGENTS.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Http11Probe is an HTTP/1.1 compliance and security tester. It sends raw TCP requ
1010

1111
## TASK A: Add a new test
1212

13-
Adding a test requires changes to **4 locations** (sometimes 3 if URL mapping is automatic).
13+
Adding a test requires changes to **5 locations** (sometimes 4 if URL mapping is automatic).
1414

1515
### Step 1 — Add the test case to the suite file
1616

@@ -215,6 +215,26 @@ Find the `{{</* cards */>}}` block and add a new card entry. Place scored tests
215215

216216
The `link` value is the filename without `.md`.
217217

218+
### Step 5 — Add a row to the RFC Requirement Dashboard
219+
220+
**File:** `docs/content/docs/rfc-requirement-dashboard.md`
221+
222+
This page classifies every test by its RFC 2119 requirement level. You must:
223+
224+
1. **Add a row** to the correct table based on the test's requirement level:
225+
- `MUST` / `MUST NOT` → "MUST-Level Requirements" table (use the "Reject with 400" sub-table if the RFC explicitly mandates 400, otherwise the "Reject (400 or Connection Close Acceptable)" sub-table)
226+
- `SHOULD` / `SHOULD NOT` → "SHOULD-Level Requirements" table
227+
- `MAY` → "MAY-Level Requirements" table
228+
- `Scored = false` → "Unscored Tests" table (regardless of RFC keyword)
229+
230+
2. **Update the counts** in:
231+
- The summary table at the top (increment the matching requirement level)
232+
- The total test count in both the `description` frontmatter and the "Total: N tests" line
233+
- The "Requirement Level by Suite" section (increment the matching suite + level)
234+
- The "RFC Section Cross-Reference" table (increment existing section count or add a new row)
235+
236+
3. **Include** the test ID, suite name, RFC link, and an exact RFC quote with the keyword bolded (e.g., `**MUST**`).
237+
218238
### Verification checklist
219239

220240
After making all changes:

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@
22

33
All notable changes to Http11Probe are documented in this file.
44

5+
## [Unreleased]
6+
7+
### Added
8+
- **9 new RFC 9110 compliance tests** sourced from [mohammed90/http-compliance-testing](https://github.com/mohammed90/http-compliance-testing):
9+
- `COMP-HEAD-NO-BODY` — HEAD response must not contain a message body (RFC 9110 §9.3.2, MUST)
10+
- `COMP-UNKNOWN-METHOD` — unrecognized method should be rejected with 501/405 (RFC 9110 §9.1, SHOULD)
11+
- `COMP-405-ALLOW` — 405 response must include Allow header (RFC 9110 §15.5.6, MUST)
12+
- `COMP-DATE-HEADER` — origin server must include Date header in responses (RFC 9110 §6.6.1, MUST)
13+
- `COMP-NO-1XX-HTTP10` — server must not send 1xx to HTTP/1.0 client (RFC 9110 §15.2, MUST NOT)
14+
- `COMP-NO-CL-IN-204` — Content-Length forbidden in 204 responses (RFC 9110 §8.6, MUST NOT)
15+
- `SMUG-CL-COMMA-TRIPLE` — three comma-separated identical CL values (RFC 9110 §8.6, unscored)
16+
- `COMP-OPTIONS-ALLOW` — OPTIONS response should include Allow header (RFC 9110 §9.3.7, SHOULD)
17+
- `COMP-CONTENT-TYPE` — response with content should include Content-Type (RFC 9110 §8.3, SHOULD)
18+
19+
### Changed
20+
- **AGENTS.md** — added Step 5 (RFC Requirement Dashboard) to the "Add a new test" task
21+
- **RFC Requirement Dashboard** — updated with all 9 new tests, counts, and cross-references
22+
- **Landing page cards** — removed hardcoded test count from RFC Requirement Dashboard subtitle
23+
524
## [2026-02-14]
625

726
### Added

docs/content/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ layout: hextra-home
2424

2525
{{< cards >}}
2626
{{< card link="probe-results" title="Leaderboard" subtitle="See which frameworks pass the most tests, ranked from best to worst compliance." icon="chart-bar" >}}
27-
{{< card link="docs/rfc-requirement-dashboard" title="RFC Requirement Dashboard" subtitle="All 148 tests classified by RFC 2119 level (MUST/SHOULD/MAY)." icon="document-search" >}}
27+
{{< card link="docs/rfc-requirement-dashboard" title="RFC Requirement Dashboard" subtitle="Every test classified by RFC 2119 requirement level (MUST/SHOULD/MAY)." icon="document-search" >}}
2828
{{< /cards >}}
2929

3030
<div style="height:60px"></div>

docs/content/docs/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Reference documentation for every test in Http11Probe, organized by topic. Each
1010

1111
{{< cards >}}
1212
{{< card link="http-overview" title="Understanding HTTP" subtitle="What HTTP is, how HTTP/1.1 works at the wire level, its history from 0.9 to 3, and alternatives." icon="globe-alt" >}}
13-
{{< card link="rfc-requirement-dashboard" title="RFC Requirement Dashboard" subtitle="All 148 tests classified by RFC 2119 level (MUST/SHOULD/MAY)." icon="document-search" >}}
13+
{{< card link="rfc-requirement-dashboard" title="RFC Requirement Dashboard" subtitle="Every test classified by RFC 2119 requirement level (MUST/SHOULD/MAY)." icon="document-search" >}}
1414
{{< card link="rfc-basics" title="RFC Basics" subtitle="What RFCs are, how to read requirement levels (MUST/SHOULD/MAY), and which RFCs define HTTP/1.1." icon="book-open" >}}
1515
{{< card link="baseline" title="Baseline" subtitle="Sanity request used to confirm the target is reachable before running negative tests." icon="check-circle" >}}
1616
{{< card link="line-endings" title="Line Endings" subtitle="CRLF requirements, bare LF handling, and bare CR rejection per RFC 9112 Section 2.2." icon="code" >}}

docs/content/docs/content-length/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ The `Content-Length` header indicates the size of the message body in bytes. Its
1919
{{< cards >}}
2020
{{< card link="cl-non-numeric" title="CL-NON-NUMERIC" subtitle="Non-numeric Content-Length value." >}}
2121
{{< card link="cl-plus-sign" title="CL-PLUS-SIGN" subtitle="Content-Length with a + prefix." >}}
22+
{{< card link="no-cl-in-204" title="NO-CL-IN-204" subtitle="Content-Length forbidden in 204 responses." >}}
2223
{{< /cards >}}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: "NO-CL-IN-204"
3+
description: "NO-CL-IN-204 test documentation"
4+
weight: 3
5+
---
6+
7+
| | |
8+
|---|---|
9+
| **Test ID** | `COMP-NO-CL-IN-204` |
10+
| **Category** | Compliance |
11+
| **RFC** | [RFC 9110 §8.6](https://www.rfc-editor.org/rfc/rfc9110#section-8.6) |
12+
| **Requirement** | MUST NOT |
13+
| **Expected** | `204` without `Content-Length` |
14+
15+
## What it sends
16+
17+
An OPTIONS request to the root path. Some servers respond with `204 No Content`, which triggers the validation.
18+
19+
```http
20+
OPTIONS / HTTP/1.1\r\n
21+
Host: localhost:8080\r\n
22+
\r\n
23+
```
24+
25+
## What the RFC says
26+
27+
> "A server MUST NOT send a Content-Length header field in any response with a status code of 1xx (Informational) or 204 (No Content)." -- RFC 9110 Section 8.6
28+
29+
## Why it matters
30+
31+
A `204 No Content` response explicitly signals that there is no body. Including `Content-Length` contradicts this, and some clients or proxies may attempt to read body bytes based on the Content-Length value. On persistent connections, this causes desync — the client reads the next response's bytes as body data for the 204, corrupting the entire connection. If the server does not return 204 for this request, the test reports a warning since the prohibition cannot be verified.
32+
33+
## Sources
34+
35+
- [RFC 9110 §8.6 -- Content-Length](https://www.rfc-editor.org/rfc/rfc9110#section-8.6)

docs/content/docs/headers/_index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ HTTP header fields follow a strict grammar: `field-name ":" OWS field-value OWS`
3030
{{< card link="header-no-colon" title="HEADER-NO-COLON" subtitle="Header line with no colon separator." >}}
3131
{{< card link="whitespace-before-headers" title="WHITESPACE-BEFORE-HEADERS" subtitle="Whitespace before the first header line." >}}
3232
{{< card link="expect-unknown" title="EXPECT-UNKNOWN" subtitle="Unknown Expect value. Should respond with 417." >}}
33+
{{< card link="date-header" title="DATE-HEADER" subtitle="Origin server must include Date header in responses." >}}
34+
{{< card link="no-1xx-http10" title="NO-1XX-HTTP10" subtitle="Server must not send 1xx to HTTP/1.0 client." >}}
35+
{{< card link="content-type-presence" title="CONTENT-TYPE" subtitle="Response with content should include Content-Type." >}}
3336
{{< /cards >}}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
title: "CONTENT-TYPE"
3+
description: "CONTENT-TYPE test documentation"
4+
weight: 12
5+
---
6+
7+
| | |
8+
|---|---|
9+
| **Test ID** | `COMP-CONTENT-TYPE` |
10+
| **Category** | Compliance |
11+
| **RFC** | [RFC 9110 §8.3](https://www.rfc-editor.org/rfc/rfc9110#section-8.3) |
12+
| **Requirement** | SHOULD |
13+
| **Expected** | `2xx` with `Content-Type` header |
14+
15+
## What it sends
16+
17+
A standard GET request. The test validates that the server includes a `Content-Type` header when the response contains a body.
18+
19+
```http
20+
GET / HTTP/1.1\r\n
21+
Host: localhost:8080\r\n
22+
\r\n
23+
```
24+
25+
## What the RFC says
26+
27+
> "A sender that generates a message containing content SHOULD generate a Content-Type header field in the message unless the intended media type of the enclosed representation is unknown to the sender." -- RFC 9110 Section 8.3
28+
29+
And:
30+
31+
> "If a Content-Type header field is not present, the recipient MAY either assume a media type of 'application/octet-stream' or examine the data to determine its type." -- RFC 9110 Section 8.3
32+
33+
## Why it matters
34+
35+
Without Content-Type, clients must guess the media type through content sniffing, which is a well-known security risk. Browsers performing MIME sniffing may interpret a response as HTML when it was intended as plain text, enabling XSS attacks. Including Content-Type is a baseline security practice.
36+
37+
## Sources
38+
39+
- [RFC 9110 §8.3 -- Content-Type](https://www.rfc-editor.org/rfc/rfc9110#section-8.3)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: "DATE-HEADER"
3+
description: "DATE-HEADER test documentation"
4+
weight: 10
5+
---
6+
7+
| | |
8+
|---|---|
9+
| **Test ID** | `COMP-DATE-HEADER` |
10+
| **Category** | Compliance |
11+
| **RFC** | [RFC 9110 §6.6.1](https://www.rfc-editor.org/rfc/rfc9110#section-6.6.1) |
12+
| **Requirement** | MUST |
13+
| **Expected** | `2xx` with `Date` header |
14+
15+
## What it sends
16+
17+
A standard GET request. The test validates that the server includes a `Date` header in its response.
18+
19+
```http
20+
GET / HTTP/1.1\r\n
21+
Host: localhost:8080\r\n
22+
\r\n
23+
```
24+
25+
## What the RFC says
26+
27+
> "An origin server with a clock MUST generate a Date header field in all 2xx (Successful), 3xx (Redirection), and 4xx (Client Error) responses, and MAY generate a Date header field in 1xx (Informational) and 5xx (Server Error) responses." -- RFC 9110 Section 6.6.1
28+
29+
## Why it matters
30+
31+
The Date header is essential for HTTP caching. Caches use it to calculate age, determine freshness, and resolve clock skew between origin servers and intermediaries. Without it, caches cannot properly compute expiration times, leading to either stale content being served or unnecessary revalidation.
32+
33+
## Sources
34+
35+
- [RFC 9110 §6.6.1 -- Date](https://www.rfc-editor.org/rfc/rfc9110#section-6.6.1)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
title: "NO-1XX-HTTP10"
3+
description: "NO-1XX-HTTP10 test documentation"
4+
weight: 11
5+
---
6+
7+
| | |
8+
|---|---|
9+
| **Test ID** | `COMP-NO-1XX-HTTP10` |
10+
| **Category** | Compliance |
11+
| **RFC** | [RFC 9110 §15.2](https://www.rfc-editor.org/rfc/rfc9110#section-15.2) |
12+
| **Requirement** | MUST NOT |
13+
| **Expected** | Non-1xx response |
14+
15+
## What it sends
16+
17+
An HTTP/1.0 POST with `Expect: 100-continue` and a body, designed to test whether the server incorrectly sends a `100 Continue` interim response to an HTTP/1.0 client.
18+
19+
```http
20+
POST / HTTP/1.0\r\n
21+
Host: localhost:8080\r\n
22+
Expect: 100-continue\r\n
23+
Content-Length: 5\r\n
24+
\r\n
25+
hello
26+
```
27+
28+
## What the RFC says
29+
30+
> "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." -- RFC 9110 Section 15.2
31+
32+
## Why it matters
33+
34+
HTTP/1.0 clients do not understand interim responses. If a server sends `100 Continue` to an HTTP/1.0 client, the client may interpret the `100` status line as a malformed final response, discard it as garbage, or enter an undefined state. This is especially dangerous in proxy chains where an HTTP/1.0 hop cannot forward 1xx responses correctly.
35+
36+
## Sources
37+
38+
- [RFC 9110 §15.2 -- Informational 1xx](https://www.rfc-editor.org/rfc/rfc9110#section-15.2)

0 commit comments

Comments
 (0)