Skip to content

Commit 6a0a217

Browse files
committed
update GenHTTP
1 parent a65d6d8 commit 6a0a217

22 files changed

Lines changed: 148 additions & 261 deletions

docs/content/docs/caching/etag-304.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ Captures the `ETag` header from the response for use in step 2.
3434
```http
3535
GET / HTTP/1.1\r\n
3636
Host: localhost:8080\r\n
37-
If-None-Match: "abc123"\r\n
37+
If-None-Match: {ETag from step 1}\r\n
3838
\r\n
3939
```
4040

41-
Sends the captured ETag value in an `If-None-Match` header. If the resource hasn't changed, the server should return `304 Not Modified`.
41+
Replays the `ETag` value captured from step 1 in an `If-None-Match` header. If the resource hasn't changed, the server should return `304 Not Modified`. If the server did not include an `ETag` header in step 1, the test reports Warn immediately.
4242

4343
## What the RFC says
4444

docs/content/docs/caching/etag-in-304.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ Captures the `ETag` header from the response.
3434
```http
3535
GET / HTTP/1.1\r\n
3636
Host: localhost:8080\r\n
37-
If-None-Match: "abc123"\r\n
37+
If-None-Match: {ETag from step 1}\r\n
3838
\r\n
3939
```
4040

41-
Sends the captured ETag. If the server returns `304`, this test checks whether the `ETag` header is present in that response.
41+
Replays the `ETag` value captured from step 1. If the server returns `304`, this test checks whether the `ETag` header is present in that response.
4242

4343
## What the RFC says
4444

docs/content/docs/caching/etag-weak.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Captures the `ETag` header from the response. If the ETag is strong (e.g., `"abc
3434
```http
3535
GET / HTTP/1.1\r\n
3636
Host: localhost:8080\r\n
37-
If-None-Match: W/"abc123"\r\n
37+
If-None-Match: {ETag from step 1, weak}\r\n
3838
\r\n
3939
```
4040

docs/content/docs/caching/inm-precedence.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ Captures the `ETag` header from the response.
3434
```http
3535
GET / HTTP/1.1\r\n
3636
Host: localhost:8080\r\n
37-
If-None-Match: "abc123"\r\n
37+
If-None-Match: {ETag from step 1}\r\n
3838
If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT\r\n
3939
\r\n
4040
```
4141

42-
The `If-None-Match` header matches the current ETag (should produce `304`), but the `If-Modified-Since` is set to epoch (should produce `200` since the resource was certainly modified after 1970). If the server returns `304`, it correctly evaluated `If-None-Match` first.
42+
Replays the `ETag` value captured from step 1 in `If-None-Match` (should produce `304`), combined with `If-Modified-Since` set to epoch (should produce `200` since the resource was certainly modified after 1970). If the server returns `304`, it correctly evaluated `If-None-Match` first.
4343

4444
## What the RFC says
4545

docs/content/docs/caching/inm-unquoted.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ Captures the `ETag` header from the response for use in step 2.
3434
```http
3535
GET / HTTP/1.1\r\n
3636
Host: localhost:8080\r\n
37-
If-None-Match: abc123\r\n
37+
If-None-Match: {ETag from step 1, unquoted}\r\n
3838
\r\n
3939
```
4040

41-
Sends the ETag value without the required surrounding double quotes. According to the RFC grammar, `entity-tag = [ weak ] opaque-tag` and `opaque-tag = DQUOTE *etagc DQUOTE` — the quotes are mandatory.
41+
Sends the ETag value captured from step 1, stripped of the required surrounding double quotes. According to the RFC grammar, `entity-tag = [ weak ] opaque-tag` and `opaque-tag = DQUOTE *etagc DQUOTE` — the quotes are mandatory.
4242

4343
## What the RFC says
4444

docs/content/docs/caching/last-modified-304.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ Captures the `Last-Modified` header from the response for use in step 2.
3434
```http
3535
GET / HTTP/1.1\r\n
3636
Host: localhost:8080\r\n
37-
If-Modified-Since: Sun, 01 Jan 2025 00:00:00 GMT\r\n
37+
If-Modified-Since: {Last-Modified from step 1}\r\n
3838
\r\n
3939
```
4040

41-
Sends the captured Last-Modified value in an `If-Modified-Since` header. If the resource hasn't changed since that date, the server should return `304 Not Modified`.
41+
Replays the `Last-Modified` value captured from step 1 in an `If-Modified-Since` header. If the resource hasn't changed since that date, the server should return `304 Not Modified`. If the server did not include a `Last-Modified` header in step 1, the test reports Warn immediately.
4242

4343
## What the RFC says
4444

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,5 @@
11
---
2-
title: Cookies
3-
description: "Cookies — Http11Probe documentation"
4-
weight: 13
2+
title: Cookie Handling
53
sidebar:
64
open: false
75
---
8-
9-
Cookie parsing is handled by framework-level parsers that run automatically on every request. Malformed `Cookie` headers can crash these parsers, cause memory issues, or produce mangled values. These tests check whether servers and frameworks survive adversarial cookie input.
10-
11-
Cookies are defined by [RFC 6265](https://www.rfc-editor.org/rfc/rfc6265) (not RFC 9110/9112), so all tests are **unscored**.
12-
13-
## Scoring
14-
15-
All cookie tests are **unscored**:
16-
17-
- **Pass** — Server handled the cookie input safely
18-
- **Warn** — Endpoint not available or non-ideal but non-dangerous behavior
19-
- **Fail** — Server crashed (500), preserved dangerous bytes, or lost data it should have parsed
20-
21-
## Echo-Based Tests
22-
23-
These tests target `/echo` and work on all servers. They check whether the server survives adversarial cookie headers without crashing.
24-
25-
{{< cards >}}
26-
{{< card link="echo" title="ECHO" subtitle="Basic Cookie header echoed back." >}}
27-
{{< card link="oversized" title="OVERSIZED" subtitle="64KB Cookie header." >}}
28-
{{< card link="empty" title="EMPTY" subtitle="Empty Cookie header value." >}}
29-
{{< card link="nul" title="NUL" subtitle="NUL byte in cookie value." >}}
30-
{{< card link="control-chars" title="CONTROL-CHARS" subtitle="Control characters in cookie value." >}}
31-
{{< card link="many-pairs" title="MANY-PAIRS" subtitle="1000 cookie key=value pairs." >}}
32-
{{< card link="malformed" title="MALFORMED" subtitle="Completely malformed cookie syntax." >}}
33-
{{< card link="multi-header" title="MULTI-HEADER" subtitle="Two separate Cookie headers." >}}
34-
{{< /cards >}}
35-
36-
## Parsed-Cookie Tests
37-
38-
These tests target `/cookie` and check whether the framework's cookie parser correctly extracts key=value pairs. Servers without a `/cookie` endpoint return 404 (Warn).
39-
40-
{{< cards >}}
41-
{{< card link="parsed-basic" title="PARSED-BASIC" subtitle="Single foo=bar cookie parsed." >}}
42-
{{< card link="parsed-multi" title="PARSED-MULTI" subtitle="Three cookies parsed from one header." >}}
43-
{{< card link="parsed-empty-val" title="PARSED-EMPTY-VAL" subtitle="Cookie with empty value." >}}
44-
{{< card link="parsed-special" title="PARSED-SPECIAL" subtitle="Spaces and = in cookie values." >}}
45-
{{< /cards >}}
Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "CONTROL-CHARS"
3-
description: "COOK-CONTROL-CHARS test documentation"
3+
description: "COOK-CONTROL-CHARS cookie test documentation"
44
weight: 5
55
---
66

@@ -9,37 +9,29 @@ weight: 5
99
| **Test ID** | `COOK-CONTROL-CHARS` |
1010
| **Category** | Cookies |
1111
| **Scored** | No |
12-
| **Expected** | `400` (rejected) or `2xx` without control chars |
12+
| **RFC Level** | N/A |
13+
| **Expected** | `400 (rejected) or 2xx without control chars` |
1314

1415
## What it sends
1516

17+
Control characters (0x01-0x03) in cookie value — dangerous if preserved.
18+
1619
```http
1720
GET /echo HTTP/1.1\r\n
1821
Host: localhost:8080\r\n
1922
Cookie: foo=\x01\x02\x03\r\n
2023
\r\n
2124
```
2225

23-
A `Cookie` header containing control characters SOH (`0x01`), STX (`0x02`), and ETX (`0x03`) as the cookie value.
24-
25-
## What the RFC says
26-
27-
> "cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E" — RFC 6265 §4.1.1
28-
29-
Control characters (`0x00-0x1F`) are explicitly excluded from the `cookie-octet` production. They are not valid in cookie values.
30-
3126
## Why it matters
3227

33-
Control characters in cookie values can cause:
34-
- **Log injection** — if the bytes reach log files, they may corrupt formatting or inject terminal escape sequences
35-
- **Parser confusion** — some parsers may interpret control characters as delimiters
36-
- **Security filter bypass** — WAFs may not inspect or sanitize non-printable bytes
28+
Control characters in cookie values violate RFC 6265's cookie-octet grammar and can enable response splitting or log injection if passed through to output.
3729

3830
## Verdicts
3931

40-
- **Pass**`400` (rejected) or `2xx` with control characters stripped/cookie dropped
41-
- **Fail**`2xx` with control characters preserved in the response body
32+
- **Pass** — 400 rejected, or 2xx with control chars stripped
33+
- **Fail** — 2xx with control chars preserved (dangerous), or 500
4234

4335
## Sources
4436

45-
- [RFC 6265 §4.1.1](https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1)cookie-octet definition
37+
- [RFC 6265 §5.4](https://www.rfc-editor.org/rfc/rfc6265#section-5.4)Cookie header

docs/content/docs/cookies/echo.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "ECHO"
3-
description: "COOK-ECHO test documentation"
3+
description: "COOK-ECHO cookie test documentation"
44
weight: 1
55
---
66

@@ -9,34 +9,29 @@ weight: 1
99
| **Test ID** | `COOK-ECHO` |
1010
| **Category** | Cookies |
1111
| **Scored** | No |
12-
| **Expected** | `2xx` with `Cookie:` in echo body |
12+
| **RFC Level** | N/A |
13+
| **Expected** | `2xx with Cookie in body` |
1314

1415
## What it sends
1516

17+
Basic Cookie header echoed back by /echo endpoint.
18+
1619
```http
1720
GET /echo HTTP/1.1\r\n
1821
Host: localhost:8080\r\n
1922
Cookie: foo=bar\r\n
2023
\r\n
2124
```
2225

23-
A standard request with a simple, valid `Cookie` header targeting the `/echo` endpoint.
24-
25-
## What the RFC says
26-
27-
> "When the user agent generates an HTTP request, the user agent MUST NOT attach more than one header field named Cookie." — RFC 6265 §5.4
28-
29-
This test sends a single, well-formed `Cookie` header. It serves as a baseline to confirm the echo endpoint reflects cookie headers.
30-
3126
## Why it matters
3227

33-
This is the baseline cookie test. If the server cannot echo back a simple `Cookie: foo=bar` header, all other cookie tests are meaningless.
28+
Baseline test — verifies the server's echo endpoint reflects Cookie headers, which is required for all other cookie tests to work.
3429

3530
## Verdicts
3631

37-
- **Pass** — 2xx response with `Cookie:` visible in the echo body
38-
- **Fail** — No response, or 2xx without the cookie header in the body
32+
- **Pass** — 2xx and body contains `Cookie:` header
33+
- **Fail** — No response or missing header
3934

4035
## Sources
4136

42-
- [RFC 6265 §5.4](https://www.rfc-editor.org/rfc/rfc6265#section-5.4)sending cookies
37+
- [RFC 6265 §5.4](https://www.rfc-editor.org/rfc/rfc6265#section-5.4)Cookie header

docs/content/docs/cookies/empty.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "EMPTY"
3-
description: "COOK-EMPTY test documentation"
3+
description: "COOK-EMPTY cookie test documentation"
44
weight: 3
55
---
66

@@ -9,34 +9,29 @@ weight: 3
99
| **Test ID** | `COOK-EMPTY` |
1010
| **Category** | Cookies |
1111
| **Scored** | No |
12-
| **Expected** | `2xx` or `400` |
12+
| **RFC Level** | N/A |
13+
| **Expected** | `2xx or 400` |
1314

1415
## What it sends
1516

17+
Empty Cookie header value — tests parser resilience.
18+
1619
```http
1720
GET /echo HTTP/1.1\r\n
1821
Host: localhost:8080\r\n
1922
Cookie: \r\n
2023
\r\n
2124
```
2225

23-
A `Cookie` header with an empty value (nothing after the colon and space).
24-
25-
## What the RFC says
26-
27-
> "cookie-header = 'Cookie:' OWS cookie-string OWS" — RFC 6265 §4.2
28-
29-
An empty cookie-string does not match `cookie-pair *( ";" SP cookie-pair )` since `cookie-pair` requires at least a name. However, servers should handle this gracefully.
30-
3126
## Why it matters
3227

33-
Empty `Cookie` headers can trigger null-pointer dereferences or empty-string edge cases in cookie parsers. The test verifies the server doesn't crash.
28+
Empty Cookie headers can cause null-reference exceptions or crashes in parsers that assume at least one key=value pair.
3429

3530
## Verdicts
3631

37-
- **Pass**`2xx` (accepted) or `400` (rejected gracefully)
38-
- **Fail**`500` or connection crash
32+
- **Pass** — 2xx or 400
33+
- **Fail** — 500 (crash)
3934

4035
## Sources
4136

42-
- [RFC 6265 §4.2](https://www.rfc-editor.org/rfc/rfc6265#section-4.2)cookie header syntax
37+
- [RFC 6265 §5.4](https://www.rfc-editor.org/rfc/rfc6265#section-5.4)Cookie header

0 commit comments

Comments
 (0)