Skip to content

Commit 1da22eb

Browse files
ShogunPandadanielleadams
authored andcommitted
http: stricter Transfer-Encoding and header separator parsing
Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com> PR-URL: nodejs-private/node-private#315 CVE-ID: CVE-2022-32215,CVE-2022-32214,CVE-2022-32212 Backport-PR-URL: nodejs-private/node-private#326
1 parent c087644 commit 1da22eb

11 files changed

Lines changed: 1037 additions & 460 deletions

‎deps/llhttp/CMakeLists.txt‎

Lines changed: 89 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,115 @@
11
cmake_minimum_required(VERSION3.5.1)
22
cmake_policy(SETCMP0069NEW)
33

4-
project(llhttp C)
4+
project(llhttp VERSION 6.0.5)
5+
include(GNUInstallDirs)
56

67
set(CMAKE_C_STANDARD 99)
78

9+
# By default build in relwithdebinfo type, supports both lowercase and uppercase
10+
if(NOTCMAKE_CONFIGURATION_TYPES)
11+
set(allowableBuileTypes DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
12+
set_property(CACHECMAKE_BUILD_TYPEPROPERTY STRINGS "${allowableBuileTypes}")
13+
if(NOTCMAKE_BUILD_TYPE)
14+
set(CMAKE_BUILD_TYPE RELWITHDEBINFO CACHESTRING""FORCE)
15+
else()
16+
string(TOUPPER${CMAKE_BUILD_TYPE}CMAKE_BUILD_TYPE)
17+
if(NOTCMAKE_BUILD_TYPEIN_LIST allowableBuileTypes)
18+
message(FATEL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}")
19+
endif()
20+
endif()
21+
endif()
22+
823
#
924
# Options
1025
#
1126
# Generic option
12-
option(BUILD_SHARED_LIBS"Build shared libraries (.dll/.so) instead of static ones (.lib/.a)"OFF)
27+
option(BUILD_SHARED_LIBS"Build shared libraries (.dll/.so)"ON)
28+
option(BUILD_STATIC_LIBS"Build static libraries (.lib/.a)"OFF)
1329

1430
# Source code
1531
set(LLHTTP_SOURCES
16-
src/llhttp.c
17-
src/http.c
18-
src/api.c
32+
${CMAKE_CURRENT_SOURCE_DIR}/src/llhttp.c
33+
${CMAKE_CURRENT_SOURCE_DIR}/src/http.c
34+
${CMAKE_CURRENT_SOURCE_DIR}/src/api.c
1935
)
2036

2137
set(LLHTTP_HEADERS
22-
include/llhttp.h
38+
${CMAKE_CURRENT_SOURCE_DIR}/include/llhttp.h
2339
)
2440

25-
add_library(llhttp)
26-
add_library(llhttp::llhttpALIASllhttp)
41+
configure_file(
42+
${CMAKE_CURRENT_SOURCE_DIR}/libllhttp.pc.in
43+
${CMAKE_CURRENT_SOURCE_DIR}/libllhttp.pc
44+
@ONLY
45+
)
2746

28-
target_sources(llhttpPRIVATE${LLHTTP_SOURCES}${LLHTTP_HEADERS})
47+
function(config_librarytarget)
48+
target_sources(${target}PRIVATE${LLHTTP_SOURCES}${LLHTTP_HEADERS})
2949

30-
# On windows with Visual Studio, add a debug postfix so that release
31-
# and debug libraries can coexist.
32-
if(MSVC)
33-
set(CMAKE_DEBUG_POSTFIX"d")
34-
endif()
50+
target_include_directories(${target}PRIVATE
51+
${CMAKE_CURRENT_SOURCE_DIR}/include
52+
)
3553

36-
target_include_directories(llhttpPUBLIC
37-
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
38-
$<INSTALL_INTERFACE:include>
39-
)
54+
set_target_properties(${target} PROPERTIES
55+
OUTPUT_NAME llhttp
56+
VERSION${PROJECT_VERSION}
57+
SOVERSION${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
58+
PUBLIC_HEADER ${LLHTTP_HEADERS}
59+
)
4060

41-
set_target_properties(llhttp PROPERTIES PUBLIC_HEADER ${LLHTTP_HEADERS})
61+
install(TARGETS${target}
62+
EXPORT llhttp
63+
LIBRARYDESTINATION${CMAKE_INSTALL_LIBDIR}
64+
ARCHIVEDESTINATION${CMAKE_INSTALL_LIBDIR}
65+
PUBLIC_HEADERDESTINATION${CMAKE_INSTALL_INCLUDEDIR}
66+
)
4267

43-
install(TARGETS llhttp
44-
EXPORT llhttp
45-
ARCHIVEDESTINATION lib
46-
PUBLIC_HEADERDESTINATION include/
47-
)
68+
install(FILES
69+
${CMAKE_CURRENT_SOURCE_DIR}/libllhttp.pc
70+
DESTINATION${CMAKE_INSTALL_LIBDIR}/pkgconfig
71+
)
4872

49-
# This is required to work with FetchContent
50-
install(EXPORT llhttp
73+
# This is required to work with FetchContent
74+
install(EXPORT llhttp
5175
FILE llhttp-config.cmake
5276
NAMESPACE llhttp::
53-
DESTINATION lib/cmake/llhttp)
77+
DESTINATION${CMAKE_INSTALL_LIBDIR}/cmake/llhttp)
78+
endfunction(config_librarytarget)
79+
80+
if(BUILD_SHARED_LIBS)
81+
add_library(llhttp_sharedSHARED
82+
${llhttp_src}
83+
)
84+
add_library(llhttp::llhttpALIASllhttp_shared)
85+
config_library(llhttp_shared)
86+
endif()
87+
88+
if(BUILD_STATIC_LIBS)
89+
add_library(llhttp_staticSTATIC
90+
${llhttp_src}
91+
)
92+
if(BUILD_SHARED_LIBS)
93+
add_library(llhttp::llhttpALIASllhttp_shared)
94+
else()
95+
add_library(llhttp::llhttpALIASllhttp_static)
96+
endif()
97+
config_library(llhttp_static)
98+
endif()
99+
100+
# On windows with Visual Studio, add a debug postfix so that release
101+
# and debug libraries can coexist.
102+
if(MSVC)
103+
set(CMAKE_DEBUG_POSTFIX"d")
104+
endif()
105+
106+
# Print project configure summary
107+
message(STATUS"")
108+
message(STATUS"")
109+
message(STATUS"Project configure summary:")
110+
message(STATUS"")
111+
message(STATUS" CMake build type .................: ${CMAKE_BUILD_TYPE}")
112+
message(STATUS" Install prefix ...................: ${CMAKE_INSTALL_PREFIX}")
113+
message(STATUS" Build shared library .............: ${BUILD_SHARED_LIBS}")
114+
message(STATUS" Build static library .............: ${BUILD_STATIC_LIBS}")
115+
message(STATUS"")

‎deps/llhttp/README.md‎

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,16 @@ if (err == HPE_OK) {
9090
parser.reason);
9191
}
9292
```
93-
For more information on API usage, please refer to [src/native/api.h](https://github.com/nodejs/llhttp/blob/master/src/native/api.h).
93+
For more information on API usage, please refer to [src/native/api.h](https://github.com/nodejs/llhttp/blob/main/src/native/api.h).
94+
95+
## Build Instructions
96+
97+
Make sure you have [Node.js](https://nodejs.org/), npm and npx installed. Then under project directory run:
98+
99+
```sh
100+
npm install
101+
make
102+
```
94103

95104
---
96105

@@ -99,20 +108,41 @@ For more information on API usage, please refer to [src/native/api.h](https://gi
99108
* Python: [pallas/pyllhttp][8]
100109
* Ruby: [metabahn/llhttp][9]
101110

102-
103111
### Using with CMake
104112

105113
If you want to use this library in a CMake project you can use the snippet below.
106114

107115
```
108116
FetchContent_Declare(llhttp
109-
URL "https://github.com/nodejs/llhttp/releases/download/v6.0.4/llhttp-release-v6.0.4.tar.gz") # Using version 6.0.4
117+
URL "https://github.com/nodejs/llhttp/releases/download/v6.0.5/llhttp-release-v6.0.5.tar.gz") # Using version 6.0.5
110118
111119
FetchContent_MakeAvailable(llhttp)
112120
113121
target_link_libraries(${EXAMPLE_PROJECT_NAME} ${PROJECT_LIBRARIES} llhttp ${PROJECT_NAME})
114122
```
115123

124+
## Building on Windows
125+
126+
### Installation
127+
128+
*`choco install git`
129+
*`choco install node`
130+
*`choco install llvm` (or install the `C++ Clang tools for Windows` optional package from the Visual Studio 2019 installer)
131+
*`choco install make` (or if you have MinGW, it comes bundled)
132+
133+
1. Ensure that `Clang` and `make` are in your system path.
134+
2. Using Git Bash, clone the repo to your preferred location.
135+
3. Cd into the cloned directory and run `npm install`
136+
5. Run `make`
137+
6. Your `repo/build` directory should now have `libllhttp.a` and `libllhttp.so` static and dynamic libraries.
138+
7. When building your executable, you can link to these libraries. Make sure to set the build folder as an include path when building so you can reference the declarations in `repo/build/llhttp.h`.
139+
140+
### A simple example on linking with the library:
141+
142+
Assuming you have an executable `main.cpp` in your current working directory, you would run: `clang++ -Os -g3 -Wall -Wextra -Wno-unused-parameter -I/path/to/llhttp/build main.cpp /path/to/llhttp/build/libllhttp.a -o main.exe`.
143+
144+
If you are getting `unresolved external symbol` linker errors you are likely attempting to build `llhttp.c` without linking it with object files from `api.c` and `http.c`.
145+
116146
#### LICENSE
117147

118148
This software is licensed under the MIT License.

‎deps/llhttp/include/llhttp.h‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#defineLLHTTP_VERSION_MAJOR 6
55
#defineLLHTTP_VERSION_MINOR 0
6-
#defineLLHTTP_VERSION_PATCH4
6+
#defineLLHTTP_VERSION_PATCH7
77

88
#ifndefLLHTTP_STRICT_MODE
99
# defineLLHTTP_STRICT_MODE 0
@@ -59,6 +59,7 @@ enum llhttp_errno {
5959
HPE_OK=0,
6060
HPE_INTERNAL=1,
6161
HPE_STRICT=2,
62+
HPE_CR_EXPECTED=25,
6263
HPE_LF_EXPECTED=3,
6364
HPE_UNEXPECTED_CONTENT_LENGTH=4,
6465
HPE_CLOSED_CONNECTION=5,
@@ -100,7 +101,8 @@ typedef enum llhttp_flags llhttp_flags_t;
100101
enumllhttp_lenient_flags {
101102
LENIENT_HEADERS=0x1,
102103
LENIENT_CHUNKED_LENGTH=0x2,
103-
LENIENT_KEEP_ALIVE=0x4
104+
LENIENT_KEEP_ALIVE=0x4,
105+
LENIENT_TRANSFER_ENCODING=0x8
104106
};
105107
typedefenumllhttp_lenient_flagsllhttp_lenient_flags_t;
106108

@@ -172,6 +174,7 @@ typedef enum llhttp_method llhttp_method_t;
172174
XX(0, OK, OK) \
173175
XX(1, INTERNAL, INTERNAL) \
174176
XX(2, STRICT, STRICT) \
177+
XX(25, CR_EXPECTED, CR_EXPECTED) \
175178
XX(3, LF_EXPECTED, LF_EXPECTED) \
176179
XX(4, UNEXPECTED_CONTENT_LENGTH, UNEXPECTED_CONTENT_LENGTH) \
177180
XX(5, CLOSED_CONNECTION, CLOSED_CONNECTION) \
@@ -374,8 +377,6 @@ LLHTTP_EXPORT
374377
voidllhttp_init(llhttp_t*parser, llhttp_type_ttype,
375378
constllhttp_settings_t*settings);
376379

377-
#if defined(__wasm__)
378-
379380
LLHTTP_EXPORT
380381
llhttp_t*llhttp_alloc(llhttp_type_ttype);
381382

@@ -400,8 +401,6 @@ int llhttp_get_status_code(llhttp_t* parser);
400401
LLHTTP_EXPORT
401402
uint8_tllhttp_get_upgrade(llhttp_t*parser);
402403

403-
#endif// defined(__wasm__)
404-
405404
/* Reset an already initialized parser back to the start state, preserving the
406405
* existing parser type, callback settings, user data, and lenient flags.
407406
*/
@@ -556,6 +555,19 @@ void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
556555
*/
557556
voidllhttp_set_lenient_keep_alive(llhttp_t*parser, intenabled);
558557

558+
/* Enables/disables lenient handling of `Transfer-Encoding` header.
559+
*
560+
* Normally `llhttp` would error when a `Transfer-Encoding` has `chunked` value
561+
* and another value after it (either in a single header or in multiple
562+
* headers whose value are internally joined using `, `).
563+
* This is mandated by the spec to reliably determine request body size and thus
564+
* avoid request smuggling.
565+
* With this flag the extra value will be parsed normally.
566+
*
567+
* **(USE AT YOUR OWN RISK)**
568+
*/
569+
voidllhttp_set_lenient_transfer_encoding(llhttp_t*parser, intenabled);
570+
559571
#ifdef__cplusplus
560572
} /* extern "C" */
561573
#endif

‎deps/llhttp/libllhttp.pc.in‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
prefix=@CMAKE_INSTALL_PREFIX@
2+
exec_prefix=@CMAKE_INSTALL_PREFIX@
3+
libdir=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@
4+
includedir=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@
5+
6+
Name:libllhttp
7+
Description:Node.js llhttp Library
8+
Version:@PROJECT_VERSION@
9+
Libs:-L${libdir}-lllhttp
10+
Cflags:-I${includedir}

‎deps/llhttp/src/api.c‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,14 @@ void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
253253
}
254254
}
255255

256+
voidllhttp_set_lenient_transfer_encoding(llhttp_t*parser, intenabled) {
257+
if (enabled) {
258+
parser->lenient_flags |= LENIENT_TRANSFER_ENCODING;
259+
} else {
260+
parser->lenient_flags &= ~LENIENT_TRANSFER_ENCODING;
261+
}
262+
}
263+
256264
/* Callbacks */
257265

258266

‎deps/llhttp/src/http.c‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ int llhttp__after_headers_complete(llhttp_t* parser, const char* p,
5252
return2;
5353
} elseif (parser->flags&F_TRANSFER_ENCODING) {
5454
if (parser->type==HTTP_REQUEST&&
55-
(parser->lenient_flags&LENIENT_CHUNKED_LENGTH) ==0) {
55+
(parser->lenient_flags&LENIENT_CHUNKED_LENGTH) ==0&&
56+
(parser->lenient_flags&LENIENT_TRANSFER_ENCODING) ==0) {
5657
/* RFC 7230 3.3.3 */
5758

5859
/* If a Transfer-Encoding header field

0 commit comments

Comments
 (0)