Backport fix for CVE-2024-27982

Resolves: RHEL-56973

Signed-off-by: Sergio Correia <scorreia@redhat.com>
This commit is contained in:
Sergio Correia 2024-10-29 09:02:24 +00:00
parent 1497f3e592
commit 37cfe13d2a
No known key found for this signature in database
GPG Key ID: D0D219ED1F7E762C
5 changed files with 210 additions and 23 deletions

2
.gitignore vendored
View File

@ -22,5 +22,3 @@
/llhttp-9.1.2-nm-dev.tgz
/llhttp-9.1.3.tar.gz
/llhttp-9.1.3-nm-dev.tgz
/llhttp-9.2.1.tar.gz
/llhttp-9.2.1-nm-dev.tgz

View File

@ -0,0 +1,198 @@
From ebfb5d982de56d8bbc87db8448e8d35a883202d3 Mon Sep 17 00:00:00 2001
From: Paolo Insogna <paolo@cowtech.it>
Date: Tue, 29 Oct 2024 09:29:50 +0000
Subject: [PATCH] fix: Do not allow OBS fold in headers by default.
Upstream backport: https://github.com/nodejs/llhttp/pull/348
---
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 +-
6 files changed, 98 insertions(+), 10 deletions(-)
diff --git a/src/llhttp/http.ts b/src/llhttp/http.ts
index d0bfd48..40eff4c 100644
--- a/src/llhttp/http.ts
+++ b/src/llhttp/http.ts
@@ -827,11 +827,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 a03242e..68ed3e0 100644
--- a/test/request/connection.md
+++ b/test/request/connection.md
@@ -374,7 +374,7 @@ off=75 message complete
### Multiple tokens with folding
-<!-- meta={"type": "request"} -->
+<!-- meta={"type": "request-lenient-headers"} -->
```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
-<!-- meta={"type": "request"} -->
+<!-- meta={"type": "request-lenient-headers"} -->
```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 8eadacf..0d3b36e 100644
--- a/test/request/invalid.md
+++ b/test/request/invalid.md
@@ -583,4 +583,89 @@ off=122 len=3 span[header_value]="ghi"
off=126 header_value complete
off=127 chunk complete
off=127 message complete
+```
+
+### Spaces before headers
+
+<!-- meta={ "type": "request" } -->
+
+```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)
+
+<!-- meta={ "type": "request-lenient-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 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 f0a5d44..de2ceb9 100644
--- a/test/request/sample.md
+++ b/test/request/sample.md
@@ -540,7 +540,7 @@ off=61 message complete
See nodejs/test/parallel/test-http-headers-obstext.js
-<!-- meta={"type": "request"} -->
+<!-- meta={"type": "request-lenient-headers"} -->
```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 0f839bc..b1b523d 100644
--- a/test/request/transfer-encoding.md
+++ b/test/request/transfer-encoding.md
@@ -893,7 +893,7 @@ off=51 error code=12 reason="Invalid character in chunk size"
## Invalid OBS fold after chunked value
-<!-- meta={"type": "request" } -->
+<!-- meta={"type": "request-lenient-headers" } -->
```http
PUT /url HTTP/1.1
Transfer-Encoding: chunked
diff --git a/test/response/transfer-encoding.md b/test/response/transfer-encoding.md
index e1fd10a..0f54c72 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
-<!-- meta={"type": "response" } -->
+<!-- meta={"type": "response-lenient-headers" } -->
```http
HTTP/1.1 200 OK
Transfer-Encoding: chunked
--
2.47.0

View File

@ -12,19 +12,6 @@ modules = "<unknown version>"
# tslib/test/validateModuleExportsMatchCommonJS
validateModuleExportsMatchCommonJS = "<unknown version>"
# Similarly, these are all just ES6 module (mjs) or CommonJS (cjs) module
# wrappers in packages that do have proper license information:
# node_modules_dev/@ungap/structured-clone/cjs
# node_modules_dev/@typescript-eslint/utils/node_modules/minimatch/dist/cjs
# node_modules_dev/@typescript-eslint/utils/node_modules/minimatch/dist/mjs
# node_modules_dev/@typescript-eslint/parser/node_modules/minimatch/dist/cjs
# node_modules_dev/@typescript-eslint/parser/node_modules/minimatch/dist/mjs
# node_modules_dev/@typescript-eslint/type-utils/node_modules/minimatch/dist/cjs
# node_modules_dev/@typescript-eslint/type-utils/node_modules/minimatch/dist/mjs
# node_modules_dev/flatted/cjs
cjs = "<unknown version>"
mjs = "<unknown version>"
# These are all “dummy” modules in the tests for resolve:
# resolve/test/module_dir/zmodules/bbb
bbb = "<unknown version>"

View File

@ -26,9 +26,9 @@
# additional source even if we do not do the re-generation ourselves.
Name: llhttp
Version: 9.2.1
%global so_version 9.2
Release: %autorelease
Version: 9.1.3
%global so_version 9.1
Release: %autorelease -b 8
Summary: Port of http_parser to llparse
# License of llhttp is (SPDX) MIT; nothing from the NodeJS dependency bundle is
@ -77,6 +77,8 @@ BuildRequires: askalono-cli
BuildRequires: licensecheck
%endif
Patch: 0001-fix-Do-not-allow-OBS-fold-in-headers-by-default.patch
%description
This project is a port of http_parser to TypeScript. llparse is used to
generate the output C source file, which could be compiled and linked with the
@ -94,7 +96,7 @@ developing applications that use llhttp.
%prep
%autosetup
%autosetup -p1
# Remove build flags specifying ISA extensions not in the architectural
# baseline from the test fixture setup.
@ -226,8 +228,10 @@ fi
export CXXFLAGS="${CXXFLAGS-} -fpermissive"
export CFLAGS="${CFLAGS-} -fpermissive"
export CLANG=gcc
# See scripts.test in package.json:
NODE_ENV=test node -r ts-node/register/type-check ./test/md-test.ts
# See scripts.mocha in package.json:
NODE_ENV=test ./node_modules/.bin/mocha \
-r ts-node/register/type-check \
test/*-test.ts
%files

View File

@ -1,2 +1,2 @@
SHA512 (llhttp-9.2.1.tar.gz) = 653a0d65226644a7d71c538da343b2cff75bc7acc8cd6473ac19d166cc77c3e00c6a9087120d9abb63a9ac6b50e408c905d5925fa96d5d46d425ee7d0e3cdf9c
SHA512 (llhttp-9.2.1-nm-dev.tgz) = 3e1453675524b58c11335fe843636dbd20d4caff4cf247038aaed23be3fd7e99326382cc6c6d6457054abb32912f725153fe0f905bca8318bc663e86d4ab3c93
SHA512 (llhttp-9.1.3.tar.gz) = 037d873eda6b27cb7ef4cbb805ec1172a76dc3ba19f8ca868029ecc2a88129f8c8de3803ce91f6a6c7a995f56ab8267f1001c93009272c34a2350160446153fa
SHA512 (llhttp-9.1.3-nm-dev.tgz) = 257ef03ba5a60e4338a6cc637829f29e98f6d2965aa206560b07f54b31d461f8eb1d41917bf7ad2538933aa9a90c12e0a663c366b62008ee263cd775a77a7dba