From 6c7e133e837b15e2ae40cd1082d5a17883880945 Mon Sep 17 00:00:00 2001 From: Paolo Insogna Date: Thu, 4 Apr 2024 13:12:44 +0200 Subject: [PATCH 1/2] fix: Do not allow OBS fold in headers by default. (#352) --- src/llhttp/http.ts | 13 +++-- test/request/connection.md | 4 +- test/request/invalid.md | 85 ++++++++++++++++++++++++++++++ test/request/sample.md | 2 +- test/request/transfer-encoding.md | 2 +- test/response/transfer-encoding.md | 2 +- tsconfig.json | 3 +- 7 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/llhttp/http.ts b/src/llhttp/http.ts index 6b94f65c..914dcf6d 100644 --- a/src/llhttp/http.ts +++ b/src/llhttp/http.ts @@ -756,11 +756,14 @@ export class HTTP { 'Missing expected LF after header value')); n('header_value_lws') - .peek([ ' ', '\t' ], - this.load('header_state', { - [HEADER_STATE.TRANSFER_ENCODING_CHUNKED]: - this.resetHeaderState(span.headerValue.start(n('header_value_start'))), - }, span.headerValue.start(n('header_value_start')))) + .peek( + [ ' ', '\t' ], + this.testLenientFlags(LENIENT_FLAGS.HEADERS, { + 1: this.load('header_state', { + [HEADER_STATE.TRANSFER_ENCODING_CHUNKED]: + this.resetHeaderState(span.headerValue.start(n('header_value_start'))), + }, span.headerValue.start(n('header_value_start'))), + }, p.error(ERROR.INVALID_HEADER_TOKEN, 'Unexpected whitespace after header value'))) .otherwise(this.setHeaderFlags(onHeaderValueComplete)); const checkTrailing = this.testFlags(FLAGS.TRAILING, { diff --git a/test/request/connection.md b/test/request/connection.md index 3c2551e4..2776423e 100644 --- a/test/request/connection.md +++ b/test/request/connection.md @@ -374,7 +374,7 @@ off=75 message complete ### Multiple tokens with folding - + ```http GET /demo HTTP/1.1 Host: example.com @@ -465,7 +465,7 @@ off=75 error code=22 reason="Pause on CONNECT/Upgrade" ### Multiple tokens with folding, LWS, and CRLF - + ```http GET /demo HTTP/1.1 Connection: keep-alive, \r\n upgrade diff --git a/test/request/invalid.md b/test/request/invalid.md index 4bdbeb1b..e119b0f5 100644 --- a/test/request/invalid.md +++ b/test/request/invalid.md @@ -402,4 +402,89 @@ off=6 url complete off=11 len=3 span[version]="1.1" off=14 version complete off=17 error code=30 reason="Unexpected space after start line" +``` + +### Spaces before headers + + + +```http +POST /hello HTTP/1.1 +Host: localhost +Foo: bar + Content-Length: 38 + +GET /bye HTTP/1.1 +Host: localhost + + +``` + +```log +off=0 message begin +off=0 len=4 span[method]="POST" +off=4 method complete +off=5 len=6 span[url]="/hello" +off=12 url complete +off=17 len=3 span[version]="1.1" +off=20 version complete +off=22 len=4 span[header_field]="Host" +off=27 header_field complete +off=28 len=9 span[header_value]="localhost" +off=39 header_value complete +off=39 len=3 span[header_field]="Foo" +off=43 header_field complete +off=44 len=3 span[header_value]="bar" +off=49 error code=10 reason="Unexpected whitespace after header value" +``` + +### Spaces before headers (lenient) + + + +```http +POST /hello HTTP/1.1 +Host: localhost +Foo: bar + Content-Length: 38 + +GET /bye HTTP/1.1 +Host: localhost + + +``` + +```log +off=0 message begin +off=0 len=4 span[method]="POST" +off=4 method complete +off=5 len=6 span[url]="/hello" +off=12 url complete +off=17 len=3 span[version]="1.1" +off=20 version complete +off=22 len=4 span[header_field]="Host" +off=27 header_field complete +off=28 len=9 span[header_value]="localhost" +off=39 header_value complete +off=39 len=3 span[header_field]="Foo" +off=43 header_field complete +off=44 len=3 span[header_value]="bar" +off=49 len=19 span[header_value]=" Content-Length: 38" +off=70 header_value complete +off=72 headers complete method=3 v=1/1 flags=0 content_length=0 +off=72 message complete +off=72 reset +off=72 message begin +off=72 len=3 span[method]="GET" +off=75 method complete +off=76 len=4 span[url]="/bye" +off=81 url complete +off=86 len=3 span[version]="1.1" +off=89 version complete +off=91 len=4 span[header_field]="Host" +off=96 header_field complete +off=97 len=9 span[header_value]="localhost" +off=108 header_value complete +off=110 headers complete method=1 v=1/1 flags=0 content_length=0 +off=110 message complete ``` \ No newline at end of file diff --git a/test/request/sample.md b/test/request/sample.md index 32ba3069..cd310f1b 100644 --- a/test/request/sample.md +++ b/test/request/sample.md @@ -497,7 +497,7 @@ off=61 message complete See nodejs/test/parallel/test-http-headers-obstext.js - + ```http GET / HTTP/1.1 X-SSL-Nonsense: -----BEGIN CERTIFICATE----- diff --git a/test/request/transfer-encoding.md b/test/request/transfer-encoding.md index 9fd99742..4521c71a 100644 --- a/test/request/transfer-encoding.md +++ b/test/request/transfer-encoding.md @@ -854,7 +854,7 @@ off=50 error code=12 reason="Invalid character in chunk size" ## Invalid OBS fold after chunked value - + ```http PUT /url HTTP/1.1 Transfer-Encoding: chunked diff --git a/test/response/transfer-encoding.md b/test/response/transfer-encoding.md index 6a2252e4..3980f622 100644 --- a/test/response/transfer-encoding.md +++ b/test/response/transfer-encoding.md @@ -370,7 +370,7 @@ off=101 error code=2 reason="Invalid character in chunk extensions quoted value" ## Invalid OBS fold after chunked value - + ```http HTTP/1.1 200 OK Transfer-Encoding: chunked diff --git a/tsconfig.json b/tsconfig.json index 01ec7c26..b0775b15 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,8 @@ "outDir": "./lib", "declaration": true, "pretty": true, - "sourceMap": true + "sourceMap": true, + "skipLibCheck": true }, "include": [ "src/**/*.ts" From 3339cf15787c66b26321ac6de0f92d1d0bee4e79 Mon Sep 17 00:00:00 2001 From: Paolo Insogna Date: Thu, 4 Apr 2024 12:13:04 +0100 Subject: [PATCH 2/2] 8.1.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 05a03c26..d97698ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "llhttp", - "version": "8.1.0", + "version": "8.1.2", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "8.1.0", + "version": "8.1.2", "license": "MIT", "dependencies": { "@types/semver": "^5.5.0", diff --git a/package.json b/package.json index d44c8121..240590a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "llhttp", - "version": "8.1.1", + "version": "8.1.2", "description": "HTTP parser in LLVM IR", "main": "lib/llhttp.js", "types": "lib/llhttp.d.ts",