You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A POST request with an unrecognized `Content-Type`.
19
+
20
+
```http
21
+
POST / HTTP/1.1\r\n
22
+
Host: localhost:8080\r\n
23
+
Content-Length: 5\r\n
24
+
Content-Type: application/x-nonsense\r\n
25
+
\r\n
26
+
hello
27
+
```
28
+
29
+
## What the RFC says
30
+
31
+
> "The 415 (Unsupported Media Type) status code indicates that the origin server is refusing to service the request because the content is in a format not supported by this method on the target resource." — RFC 9110 §15.5.16
32
+
33
+
The server is not required to reject unsupported content types — it may choose to accept the body regardless of the declared type.
34
+
35
+
## Why it matters
36
+
37
+
A server that validates `Content-Type` and returns `415` for unsupported formats provides better API hygiene, helping clients detect misconfigured requests early. A server that ignores unknown content types and processes the body anyway is also valid behavior — many servers treat the body as opaque bytes regardless of the declared type.
38
+
39
+
## Verdicts
40
+
41
+
-**Pass** — Server returns `415` (validates content type) or `2xx` (accepts any type)
A GET request with a syntactically invalid `Range` header.
19
+
20
+
```http
21
+
GET / HTTP/1.1\r\n
22
+
Host: localhost:8080\r\n
23
+
Range: bytes=abc-xyz\r\n
24
+
\r\n
25
+
```
26
+
27
+
The range value `abc-xyz` does not match the required integer format.
28
+
29
+
## What the RFC says
30
+
31
+
> "A server MAY ignore the Range header field." — RFC 9110 §14.2
32
+
33
+
> "An origin server MUST ignore a Range header field that contains a range unit it does not understand. A proxy MAY discard a Range header field that contains a range unit it does not understand." — RFC 9110 §14.2
34
+
35
+
> "A server that supports range requests MAY ignore or reject a Range header field that consists of more than two overlapping ranges, or a set of many small ranges that are not listed in ascending order, since both are indications of either a broken client or a deliberate denial-of-service attack." — RFC 9110 §14.2
36
+
37
+
## Why it matters
38
+
39
+
A server that receives an unparseable Range value should either ignore it (serve the full resource with `200`) or reject it with `416 Range Not Satisfiable`. Returning `206 Partial Content` with bogus range values could expose unexpected data or cause client-side parsing errors.
40
+
41
+
## Verdicts
42
+
43
+
-**Pass** — Server returns `2xx` (ignoring the invalid range) or `416`
A GET request with an `Accept` header requesting a non-existent media type.
19
+
20
+
```http
21
+
GET / HTTP/1.1\r\n
22
+
Host: localhost:8080\r\n
23
+
Accept: application/x-nonsense\r\n
24
+
\r\n
25
+
```
26
+
27
+
## What the RFC says
28
+
29
+
> "A request without any Accept header field implies that the user agent will accept any media type in response." — RFC 9110 §12.5.1
30
+
31
+
> "If the header field is present in a request and none of the available representations for the response have a media type that is listed as acceptable, the origin server can either honor the header field by sending a 406 (Not Acceptable) response or disregard the header field by treating the response as if it is not subject to content negotiation for that request." — RFC 9110 §12.5.1
32
+
33
+
## Why it matters
34
+
35
+
Content negotiation allows servers to serve different representations of a resource based on client capabilities. A server that returns `406 Not Acceptable` for unrecognized media types actively enforces content negotiation. A server that ignores the `Accept` header and serves a default representation is also compliant — the RFC explicitly allows both behaviors.
36
+
37
+
## Verdicts
38
+
39
+
-**Pass** — Server returns `406 Not Acceptable` (enforces content negotiation)
40
+
-**Warn** — Server returns `2xx` (ignores Accept, serves default representation)
41
+
-**Fail** — Server returns an unexpected error status
Sends a standard GET request and checks whether the `Date` response header uses the preferred IMF-fixdate format.
19
+
20
+
```http
21
+
GET / HTTP/1.1\r\n
22
+
Host: localhost:8080\r\n
23
+
\r\n
24
+
```
25
+
26
+
The test inspects the `Date` header value in the response.
27
+
28
+
## What the RFC says
29
+
30
+
> "An HTTP-date value represents time as an instance of Coordinated Universal Time (UTC). The first two formats [IMF-fixdate and rfc850-date] indicate UTC by the three-letter abbreviation for Greenwich Mean Time, 'GMT'... **A recipient that parses a timestamp value in an HTTP field MUST accept all three HTTP-date formats.**" -- RFC 9110 §5.6.7
> "A sender MUST generate timestamps in the IMF-fixdate format." -- RFC 9110 §5.6.7 (quoted from RFC 7231 §7.1.1.1, carried forward)
35
+
36
+
The preferred format is **IMF-fixdate**:
37
+
38
+
```
39
+
Sun, 06 Nov 1994 08:49:37 GMT
40
+
```
41
+
42
+
## Why it matters
43
+
44
+
While all three date formats are valid for *recipients* to accept, **senders** (including origin servers) should generate the IMF-fixdate format. Servers using obsolete formats (RFC 850 or asctime) are technically non-conforming senders, though recipients must still parse them.
45
+
46
+
## Verdicts
47
+
48
+
-**Pass** -- Date header present and uses IMF-fixdate format
49
+
-**Warn** -- Date header missing or uses a non-standard format
A POST request with two `Content-Type` headers that have conflicting values.
19
+
20
+
```http
21
+
POST / HTTP/1.1\r\n
22
+
Host: localhost:8080\r\n
23
+
Content-Length: 5\r\n
24
+
Content-Type: text/plain\r\n
25
+
Content-Type: text/html\r\n
26
+
\r\n
27
+
hello
28
+
```
29
+
30
+
## What the RFC says
31
+
32
+
> "A sender MUST NOT generate multiple header fields with the same field name in a message unless either the entire field value for that header field is defined as a comma-separated list or the header field is a well-known exception." — RFC 9110 §5.3
33
+
34
+
> "A recipient MAY combine multiple header fields with the same field name into one 'field-name: field-value' pair... by appending each subsequent field value to the combined field value in order, separated by a comma." — RFC 9110 §5.3
35
+
36
+
`Content-Type` is not a list-based header — it has a single value. Duplicate `Content-Type` headers with different values create ambiguity about which value the server uses.
37
+
38
+
## Why it matters
39
+
40
+
When a proxy and origin server disagree on which `Content-Type` to use, it can lead to content-type confusion attacks. An attacker could craft a request that a proxy interprets as `text/plain` while the origin processes as `text/html`, enabling XSS or other injection attacks.
41
+
42
+
## Verdicts
43
+
44
+
-**Pass** — Server rejects with `400` or closes the connection
45
+
-**Warn** — Server accepts with `2xx` (silently picks one value)
46
+
-**Fail** — Server returns an unexpected error status
A GET request with a ~7900-character path (well under 8000 octets total for the request-line).
19
+
20
+
```http
21
+
GET /aaaa...aaa HTTP/1.1\r\n
22
+
Host: localhost:8080\r\n
23
+
\r\n
24
+
```
25
+
26
+
The path contains 7900 repetitions of `a`.
27
+
28
+
## What the RFC says
29
+
30
+
> "A server that receives a request-target longer than any URI it wishes to parse MUST respond with a 414 (URI Too Long) status code." — RFC 9112 §3
31
+
32
+
> "It is RECOMMENDED that all HTTP senders and recipients support, at a minimum, request-line lengths of 8000 octets." — RFC 9112 §3
33
+
34
+
## Why it matters
35
+
36
+
Servers that reject URLs well within the 8000-octet recommendation may break legitimate applications that use long query strings or path parameters. This test verifies the server can handle a request-line just under the recommended minimum.
37
+
38
+
This is the inverse of `MAL-LONG-URL`, which tests rejection of extremely long URLs (~100KB). Together they verify a server has reasonable upper and lower bounds.
39
+
40
+
## Verdicts
41
+
42
+
-**Pass** — Server returns any status other than `414`
43
+
-**Fail** — Server returns `414 URI Too Long`
44
+
-**Warn** — Server closes the connection without a response
A GET request with an unencoded space inside the request-target.
19
+
20
+
```http
21
+
GET /pa th HTTP/1.1\r\n
22
+
Host: localhost:8080\r\n
23
+
\r\n
24
+
```
25
+
26
+
The request-target `/pa th` contains a bare space character (0x20) which is not a valid URI character.
27
+
28
+
## What the RFC says
29
+
30
+
> "Recipients of an invalid request-line SHOULD respond with either a 400 (Bad Request) error or a 301 (Moved Permanently) redirect with the request-target properly encoded." — RFC 9112 §3.2
The space character is the delimiter between the method, request-target, and HTTP-version in the request-line. An unencoded space in the target makes the request-line ambiguous — the parser sees `GET /pa th HTTP/1.1` as having four tokens instead of three.
35
+
36
+
## Why it matters
37
+
38
+
A server that accepts a bare space in the request-target must be performing heuristic parsing to guess where the target ends. This ambiguity is a classic source of request smuggling and cache poisoning vulnerabilities, where different parsers in a chain disagree on the boundaries of the request-line.
39
+
40
+
## Verdicts
41
+
42
+
-**Pass** — Server rejects with `400` or closes the connection
0 commit comments