Skip to content

Commit 66b6f10

Browse files
committed
add lenitent-host-header test
1 parent c168e8e commit 66b6f10

6 files changed

Lines changed: 73 additions & 36 deletions

File tree

src/llhttp/http.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,12 +551,12 @@ export class HTTP {
551551
}
552552

553553
private buildHostCheck(next: Node): Node {
554-
// Check if the lentient flag given is not set to HOST_HEADER
554+
// Check if the lentient flag given is set to HOST_HEADER
555555
// This will reject repetative versions of the host header
556556
const p = this.llparse;
557557
return this.testLenientFlags(
558-
~LENIENT_FLAGS.HOST_HEADER,
559-
{1: next},
558+
LENIENT_FLAGS.HOST_HEADER,
559+
{1: next},
560560
this.testFlags(
561561
FLAGS.HOST_SEEN,
562562
{1: p.error(ERROR.HOST_PREVIOUSLY_SEEN, "host provided multiple times.")},
@@ -1189,7 +1189,7 @@ export class HTTP {
11891189
// before leaving header state if Host is not set to being
11901190
// relaxed see if no host has been provided at all...
11911191
return this.testLenientFlags(
1192-
~LENIENT_FLAGS.HOST_HEADER,
1192+
LENIENT_FLAGS.HOST_HEADER,
11931193
{1:this.testFlags(
11941194
FLAGS.HOST_SEEN,
11951195
{1: beforeHeadersComplete},

test/fixtures/extra.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ void llhttp__test_init_response_lenient_header_value_relaxed(llparse_t* s) {
201201
s->lenient_flags |= LENIENT_HEADER_VALUE_RELAXED;
202202
}
203203

204-
void llhttp__test_init_request_lenient_host_header_relaxed(llparse_t* s) {
204+
void llhttp__test_init_request_lenient_host_header(llparse_t* s) {
205205
llhttp__test_init_request(s);
206206
s->lenient_flags |= LENIENT_HOST_HEADER;
207207
}

test/fixtures/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export type TestType = 'request' | 'response' | 'request-finish' | 'response-fin
2424
'request-lenient-optional-crlf-after-chunk' | 'response-lenient-optional-crlf-after-chunk' |
2525
'request-lenient-spaces-after-chunk-size' | 'response-lenient-spaces-after-chunk-size' |
2626
'request-lenient-header-value-relaxed' | 'response-lenient-header-value-relaxed' |
27+
'request-lenient-host-header' |
2728
'none' | 'url';
2829

2930
export const allowedTypes: TestType[] = [
@@ -53,6 +54,7 @@ export const allowedTypes: TestType[] = [
5354
'response-lenient-spaces-after-chunk-size',
5455
'request-lenient-header-value-relaxed',
5556
'response-lenient-header-value-relaxed',
57+
'request-lenient-host-header'
5658
];
5759

5860
const BUILD_DIR = path.join(__dirname, '..', 'tmp');

test/md-test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,11 @@ function run(name: string): void {
227227
}
228228
}
229229

230+
230231
run('request/sample');
231232
run('request/lenient-headers');
232233
run('request/lenient-header-value-relaxed');
234+
run('request/lenient-host-header');
233235
run('request/lenient-version');
234236
run('request/method');
235237
run('request/uri');
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
Relaxed host header
2+
===================
3+
4+
Relaxed host header mode: accepts multiple host headers
5+
this is meant to stop redirection or injection attacks
6+
and other unusual behaviors.
7+
8+
## multiple host headers (relaxed)
9+
When HOST_HEADER is not set, it should allow multiple hosts to be set.
10+
11+
<!-- meta={"type": "request"} -->
12+
13+
```http
14+
GET / HTTP/1.1
15+
host: www.python.org
16+
host: llhttp.org
17+
18+
19+
```
20+
```log
21+
off=0 message begin
22+
off=0 len=3 span[method]="GET"
23+
off=3 method complete
24+
off=4 len=4 span[url]="/url"
25+
off=9 url complete
26+
off=9 len=4 span[protocol]="HTTP"
27+
off=13 protocol complete
28+
off=14 len=3 span[version]="1.1"
29+
off=17 version complete
30+
off=19 len=4 span[header_field] = "host"
31+
off=24 len=10 span[header_value] = "www.python.org"
32+
off=35 len=4 span[header_field] = "host"
33+
off=40 len=10 span[header_field] = "llhttp.org"
34+
```
35+
36+
37+
## Invalid Hosts (strict)
38+
39+
HOST_HEADER if enabled this will not allow multiple headers to be set.
40+
41+
<!-- meta={"type": "request-lenient-host-header"} -->
42+
43+
```http
44+
GET /url HTTP/1.1
45+
host: www.python.org
46+
host: llhttp.org
47+
48+
49+
```
50+
51+
```log
52+
off=0 message begin
53+
off=0 len=3 span[method]="GET"
54+
off=3 method complete
55+
off=4 len=4 span[url]="/url"
56+
off=9 url complete
57+
off=9 len=4 span[protocol]="HTTP"
58+
off=13 protocol complete
59+
off=14 len=3 span[version]="1.1"
60+
off=17 version complete
61+
off=19 len=4 span[header_field] = "host"
62+
off=24 len=10 span[header_value] = "www.python.org"
63+
off=19 len=4 error code=40
64+
```

test/request/lenitent-host-header.md

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)