Skip to content

Commit 6c7e133

Browse files
authored
fix: Do not allow OBS fold in headers by default. (#352)
1 parent 7e18596 commit 6c7e133

7 files changed

Lines changed: 100 additions & 11 deletions

File tree

src/llhttp/http.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -756,11 +756,14 @@ export class HTTP {
756756
'Missing expected LF after header value'));
757757

758758
n('header_value_lws')
759-
.peek([ ' ', '\t' ],
760-
this.load('header_state', {
761-
[HEADER_STATE.TRANSFER_ENCODING_CHUNKED]:
762-
this.resetHeaderState(span.headerValue.start(n('header_value_start'))),
763-
}, span.headerValue.start(n('header_value_start'))))
759+
.peek(
760+
[ ' ', '\t' ],
761+
this.testLenientFlags(LENIENT_FLAGS.HEADERS, {
762+
1: this.load('header_state', {
763+
[HEADER_STATE.TRANSFER_ENCODING_CHUNKED]:
764+
this.resetHeaderState(span.headerValue.start(n('header_value_start'))),
765+
}, span.headerValue.start(n('header_value_start'))),
766+
}, p.error(ERROR.INVALID_HEADER_TOKEN, 'Unexpected whitespace after header value')))
764767
.otherwise(this.setHeaderFlags(onHeaderValueComplete));
765768

766769
const checkTrailing = this.testFlags(FLAGS.TRAILING, {

test/request/connection.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ off=75 message complete
374374

375375
### Multiple tokens with folding
376376

377-
<!-- meta={"type": "request"} -->
377+
<!-- meta={"type": "request-lenient-headers"} -->
378378
```http
379379
GET /demo HTTP/1.1
380380
Host: example.com
@@ -465,7 +465,7 @@ off=75 error code=22 reason="Pause on CONNECT/Upgrade"
465465

466466
### Multiple tokens with folding, LWS, and CRLF
467467

468-
<!-- meta={"type": "request"} -->
468+
<!-- meta={"type": "request-lenient-headers"} -->
469469
```http
470470
GET /demo HTTP/1.1
471471
Connection: keep-alive, \r\n upgrade

test/request/invalid.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,4 +402,89 @@ off=6 url complete
402402
off=11 len=3 span[version]="1.1"
403403
off=14 version complete
404404
off=17 error code=30 reason="Unexpected space after start line"
405+
```
406+
407+
### Spaces before headers
408+
409+
<!-- meta={ "type": "request" } -->
410+
411+
```http
412+
POST /hello HTTP/1.1
413+
Host: localhost
414+
Foo: bar
415+
Content-Length: 38
416+
417+
GET /bye HTTP/1.1
418+
Host: localhost
419+
420+
421+
```
422+
423+
```log
424+
off=0 message begin
425+
off=0 len=4 span[method]="POST"
426+
off=4 method complete
427+
off=5 len=6 span[url]="/hello"
428+
off=12 url complete
429+
off=17 len=3 span[version]="1.1"
430+
off=20 version complete
431+
off=22 len=4 span[header_field]="Host"
432+
off=27 header_field complete
433+
off=28 len=9 span[header_value]="localhost"
434+
off=39 header_value complete
435+
off=39 len=3 span[header_field]="Foo"
436+
off=43 header_field complete
437+
off=44 len=3 span[header_value]="bar"
438+
off=49 error code=10 reason="Unexpected whitespace after header value"
439+
```
440+
441+
### Spaces before headers (lenient)
442+
443+
<!-- meta={ "type": "request-lenient-headers" } -->
444+
445+
```http
446+
POST /hello HTTP/1.1
447+
Host: localhost
448+
Foo: bar
449+
Content-Length: 38
450+
451+
GET /bye HTTP/1.1
452+
Host: localhost
453+
454+
455+
```
456+
457+
```log
458+
off=0 message begin
459+
off=0 len=4 span[method]="POST"
460+
off=4 method complete
461+
off=5 len=6 span[url]="/hello"
462+
off=12 url complete
463+
off=17 len=3 span[version]="1.1"
464+
off=20 version complete
465+
off=22 len=4 span[header_field]="Host"
466+
off=27 header_field complete
467+
off=28 len=9 span[header_value]="localhost"
468+
off=39 header_value complete
469+
off=39 len=3 span[header_field]="Foo"
470+
off=43 header_field complete
471+
off=44 len=3 span[header_value]="bar"
472+
off=49 len=19 span[header_value]=" Content-Length: 38"
473+
off=70 header_value complete
474+
off=72 headers complete method=3 v=1/1 flags=0 content_length=0
475+
off=72 message complete
476+
off=72 reset
477+
off=72 message begin
478+
off=72 len=3 span[method]="GET"
479+
off=75 method complete
480+
off=76 len=4 span[url]="/bye"
481+
off=81 url complete
482+
off=86 len=3 span[version]="1.1"
483+
off=89 version complete
484+
off=91 len=4 span[header_field]="Host"
485+
off=96 header_field complete
486+
off=97 len=9 span[header_value]="localhost"
487+
off=108 header_value complete
488+
off=110 headers complete method=1 v=1/1 flags=0 content_length=0
489+
off=110 message complete
405490
```

test/request/sample.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ off=61 message complete
497497

498498
See nodejs/test/parallel/test-http-headers-obstext.js
499499

500-
<!-- meta={"type": "request"} -->
500+
<!-- meta={"type": "request-lenient-headers"} -->
501501
```http
502502
GET / HTTP/1.1
503503
X-SSL-Nonsense: -----BEGIN CERTIFICATE-----

test/request/transfer-encoding.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ off=50 error code=12 reason="Invalid character in chunk size"
854854

855855
## Invalid OBS fold after chunked value
856856

857-
<!-- meta={"type": "request", "mode": "strict"} -->
857+
<!-- meta={"type": "request-lenient-headers", "mode": "strict"} -->
858858
```http
859859
PUT /url HTTP/1.1
860860
Transfer-Encoding: chunked

test/response/transfer-encoding.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ off=101 error code=2 reason="Invalid character in chunk extensions quoted value"
370370

371371
## Invalid OBS fold after chunked value
372372

373-
<!-- meta={"type": "response" } -->
373+
<!-- meta={"type": "response-lenient-headers" } -->
374374
```http
375375
HTTP/1.1 200 OK
376376
Transfer-Encoding: chunked

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"outDir": "./lib",
88
"declaration": true,
99
"pretty": true,
10-
"sourceMap": true
10+
"sourceMap": true,
11+
"skipLibCheck": true
1112
},
1213
"include": [
1314
"src/**/*.ts"

0 commit comments

Comments
 (0)