Skip to content

Commit 338e411

Browse files
authored
fix: Do not allow OBS fold in headers by default. (#350)
1 parent 0ed1d84 commit 338e411

8 files changed

Lines changed: 89 additions & 11 deletions

File tree

src/llhttp/http.ts

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

669669
n('header_value_lws')
670-
.peek([ ' ', '\t' ],
671-
this.load('header_state', {
672-
[HEADER_STATE.TRANSFER_ENCODING_CHUNKED]:
673-
this.resetHeaderState(span.headerValue.start(n('header_value_start'))),
674-
}, span.headerValue.start(n('header_value_start'))))
670+
.peek(
671+
[ ' ', '\t' ],
672+
this.testLenientFlags(LENIENT_FLAGS.HEADERS, {
673+
1: this.load('header_state', {
674+
[HEADER_STATE.TRANSFER_ENCODING_CHUNKED]:
675+
this.resetHeaderState(span.headerValue.start(n('header_value_start'))),
676+
}, span.headerValue.start(n('header_value_start'))),
677+
}, p.error(ERROR.INVALID_HEADER_TOKEN, 'Unexpected whitespace after header value')))
675678
.otherwise(this.setHeaderFlags(onHeaderValueComplete));
676679

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

test/md-test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ const http: IFixtureMap = {
8686
'request-lenient-version': buildMode( 'loose', 'request-lenient-version'),
8787
'response': buildMode('loose', 'response'),
8888
'response-finish': buildMode('loose', 'response-finish'),
89+
'response-lenient-headers': buildMode( 'loose', 'response-lenient-headers'),
8990
'response-lenient-keep-alive': buildMode( 'loose', 'response-lenient-keep-alive'),
9091
'response-lenient-version': buildMode( 'loose', 'response-lenient-version'),
9192
'url': buildMode('loose', 'url'),
@@ -101,6 +102,7 @@ const http: IFixtureMap = {
101102
'request-lenient-version': buildMode( 'strict', 'request-lenient-version'),
102103
'response': buildMode('strict', 'response'),
103104
'response-finish': buildMode('strict', 'response-finish'),
105+
'response-lenient-headers': buildMode('strict', 'response-lenient-headers'),
104106
'response-lenient-keep-alive': buildMode('strict', 'response-lenient-keep-alive'),
105107
'response-lenient-version': buildMode( 'strict', 'response-lenient-version'),
106108
'url': buildMode('strict', 'url'),

test/request/connection.md

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

315315
### Multiple tokens with folding
316316

317-
<!-- meta={"type": "request"} -->
317+
<!-- meta={"type": "request-lenient-headers"} -->
318318
```http
319319
GET /demo HTTP/1.1
320320
Host: example.com
@@ -397,7 +397,7 @@ off=75 error code=22 reason="Pause on CONNECT/Upgrade"
397397

398398
### Multiple tokens with folding, LWS, and CRLF
399399

400-
<!-- meta={"type": "request"} -->
400+
<!-- meta={"type": "request-lenient-headers"} -->
401401
```http
402402
GET /demo HTTP/1.1
403403
Connection: keep-alive, \r\n upgrade

test/request/invalid.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,76 @@ off=0 message begin
330330
off=4 len=1 span[url]="/"
331331
off=6 url complete
332332
off=14 error code=9 reason="Invalid HTTP version"
333+
```
334+
335+
### Spaces before headers
336+
337+
<!-- meta={ "type": "request" } -->
338+
339+
```http
340+
POST /hello HTTP/1.1
341+
Host: localhost
342+
Foo: bar
343+
Content-Length: 38
344+
345+
GET /bye HTTP/1.1
346+
Host: localhost
347+
348+
349+
```
350+
351+
```log
352+
off=0 message begin
353+
off=5 len=6 span[url]="/hello"
354+
off=12 url complete
355+
off=22 len=4 span[header_field]="Host"
356+
off=27 header_field complete
357+
off=28 len=9 span[header_value]="localhost"
358+
off=39 header_value complete
359+
off=39 len=3 span[header_field]="Foo"
360+
off=43 header_field complete
361+
off=44 len=3 span[header_value]="bar"
362+
off=49 error code=10 reason="Unexpected whitespace after header value"
363+
```
364+
365+
### Spaces before headers (lenient)
366+
367+
<!-- meta={ "type": "request-lenient-headers" } -->
368+
369+
```http
370+
POST /hello HTTP/1.1
371+
Host: localhost
372+
Foo: bar
373+
Content-Length: 38
374+
375+
GET /bye HTTP/1.1
376+
Host: localhost
377+
378+
379+
```
380+
381+
```log
382+
off=0 message begin
383+
off=5 len=6 span[url]="/hello"
384+
off=12 url complete
385+
off=22 len=4 span[header_field]="Host"
386+
off=27 header_field complete
387+
off=28 len=9 span[header_value]="localhost"
388+
off=39 header_value complete
389+
off=39 len=3 span[header_field]="Foo"
390+
off=43 header_field complete
391+
off=44 len=3 span[header_value]="bar"
392+
off=49 len=19 span[header_value]=" Content-Length: 38"
393+
off=70 header_value complete
394+
off=72 headers complete method=3 v=1/1 flags=0 content_length=0
395+
off=72 message complete
396+
off=72 message begin
397+
off=76 len=4 span[url]="/bye"
398+
off=81 url complete
399+
off=91 len=4 span[header_field]="Host"
400+
off=96 header_field complete
401+
off=97 len=9 span[header_value]="localhost"
402+
off=108 header_value complete
403+
off=110 headers complete method=1 v=1/1 flags=0 content_length=0
404+
off=110 message complete
333405
```

test/request/sample.md

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

440440
See nodejs/test/parallel/test-http-headers-obstext.js
441441

442-
<!-- meta={"type": "request"} -->
442+
<!-- meta={"type": "request-lenient-headers"} -->
443443
```http
444444
GET / HTTP/1.1
445445
X-SSL-Nonsense: -----BEGIN CERTIFICATE-----

test/request/transfer-encoding.md

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

606606
## Invalid OBS fold after chunked value
607607

608-
<!-- meta={"type": "request", "mode": "strict"} -->
608+
<!-- meta={"type": "request-lenient-headers", "mode": "strict"} -->
609609
```http
610610
PUT /url HTTP/1.1
611611
Transfer-Encoding: chunked

test/response/transfer-encoding.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ off=78 len=1 span[body]=lf
140140

141141
## Invalid OBS fold after chunked value
142142

143-
<!-- meta={"type": "response" } -->
143+
<!-- meta={"type": "response-lenient-headers"} -->
144144
```http
145145
HTTP/1.1 200 OK
146146
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)