Critical severityNVD Advisory· Published Jul 14, 2022· Updated Apr 30, 2025
CVE-2022-32213
CVE-2022-32213
Description
The llhttp parser <v14.20.1, <v16.17.1 and <v18.9.1 in the http module in Node.js does not correctly parse and validate Transfer-Encoding headers and can lead to HTTP Request Smuggling (HRS).
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
llhttpnpm | < 6.0.7 | 6.0.7 |
Affected products
1Patches
16 files changed · +910 −445
CMakeLists.txt+89 −27 modified@@ -1,53 +1,115 @@ cmake_minimum_required(VERSION 3.5.1) cmake_policy(SET CMP0069 NEW) -project(llhttp C) +project(llhttp VERSION 6.0.5) +include(GNUInstallDirs) set(CMAKE_C_STANDARD 99) +# By default build in relwithdebinfo type, supports both lowercase and uppercase +if(NOT CMAKE_CONFIGURATION_TYPES) + set(allowableBuileTypes DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${allowableBuileTypes}") + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE RELWITHDEBINFO CACHE STRING "" FORCE) + else() + string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) + if(NOT CMAKE_BUILD_TYPE IN_LIST allowableBuileTypes) + message(FATEL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}") + endif() + endif() +endif() + # # Options # # Generic option -option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF) +option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so)" ON) +option(BUILD_STATIC_LIBS "Build static libraries (.lib/.a)" OFF) # Source code set(LLHTTP_SOURCES - src/llhttp.c - src/http.c - src/api.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/llhttp.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/http.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/api.c ) set(LLHTTP_HEADERS - include/llhttp.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/llhttp.h ) -add_library(llhttp) -add_library(llhttp::llhttp ALIAS llhttp) +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/libllhttp.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/libllhttp.pc + @ONLY +) -target_sources(llhttp PRIVATE ${LLHTTP_SOURCES} ${LLHTTP_HEADERS}) +function(config_library target) + target_sources(${target} PRIVATE ${LLHTTP_SOURCES} ${LLHTTP_HEADERS}) -# On windows with Visual Studio, add a debug postfix so that release -# and debug libraries can coexist. -if(MSVC) - set(CMAKE_DEBUG_POSTFIX "d") -endif() + target_include_directories(${target} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) -target_include_directories(llhttp PUBLIC - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> - $<INSTALL_INTERFACE:include> -) + set_target_properties(${target} PROPERTIES + OUTPUT_NAME llhttp + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + PUBLIC_HEADER ${LLHTTP_HEADERS} + ) -set_target_properties(llhttp PROPERTIES PUBLIC_HEADER ${LLHTTP_HEADERS}) + install(TARGETS ${target} + EXPORT llhttp + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) -install(TARGETS llhttp - EXPORT llhttp - ARCHIVE DESTINATION lib - PUBLIC_HEADER DESTINATION include/ -) + install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/libllhttp.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + ) -# This is required to work with FetchContent -install(EXPORT llhttp + # This is required to work with FetchContent + install(EXPORT llhttp FILE llhttp-config.cmake NAMESPACE llhttp:: - DESTINATION lib/cmake/llhttp) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/llhttp) +endfunction(config_library target) + +if(BUILD_SHARED_LIBS) + add_library(llhttp_shared SHARED + ${llhttp_src} + ) + add_library(llhttp::llhttp ALIAS llhttp_shared) + config_library(llhttp_shared) +endif() + +if(BUILD_STATIC_LIBS) + add_library(llhttp_static STATIC + ${llhttp_src} + ) + if(BUILD_SHARED_LIBS) + add_library(llhttp::llhttp ALIAS llhttp_shared) + else() + add_library(llhttp::llhttp ALIAS llhttp_static) + endif() + config_library(llhttp_static) +endif() + +# On windows with Visual Studio, add a debug postfix so that release +# and debug libraries can coexist. +if(MSVC) + set(CMAKE_DEBUG_POSTFIX "d") +endif() + +# Print project configure summary +message(STATUS "") +message(STATUS "") +message(STATUS "Project configure summary:") +message(STATUS "") +message(STATUS " CMake build type .................: ${CMAKE_BUILD_TYPE}") +message(STATUS " Install prefix ...................: ${CMAKE_INSTALL_PREFIX}") +message(STATUS " Build shared library .............: ${BUILD_SHARED_LIBS}") +message(STATUS " Build static library .............: ${BUILD_STATIC_LIBS}") +message(STATUS "")
include/llhttp.h+18 −6 modified@@ -3,7 +3,7 @@ #define LLHTTP_VERSION_MAJOR 6 #define LLHTTP_VERSION_MINOR 0 -#define LLHTTP_VERSION_PATCH 6 +#define LLHTTP_VERSION_PATCH 7 #ifndef LLHTTP_STRICT_MODE # define LLHTTP_STRICT_MODE 0 @@ -59,6 +59,7 @@ enum llhttp_errno { HPE_OK = 0, HPE_INTERNAL = 1, HPE_STRICT = 2, + HPE_CR_EXPECTED = 25, HPE_LF_EXPECTED = 3, HPE_UNEXPECTED_CONTENT_LENGTH = 4, HPE_CLOSED_CONNECTION = 5, @@ -100,7 +101,8 @@ typedef enum llhttp_flags llhttp_flags_t; enum llhttp_lenient_flags { LENIENT_HEADERS = 0x1, LENIENT_CHUNKED_LENGTH = 0x2, - LENIENT_KEEP_ALIVE = 0x4 + LENIENT_KEEP_ALIVE = 0x4, + LENIENT_TRANSFER_ENCODING = 0x8 }; typedef enum llhttp_lenient_flags llhttp_lenient_flags_t; @@ -172,6 +174,7 @@ typedef enum llhttp_method llhttp_method_t; XX(0, OK, OK) \ XX(1, INTERNAL, INTERNAL) \ XX(2, STRICT, STRICT) \ + XX(25, CR_EXPECTED, CR_EXPECTED) \ XX(3, LF_EXPECTED, LF_EXPECTED) \ XX(4, UNEXPECTED_CONTENT_LENGTH, UNEXPECTED_CONTENT_LENGTH) \ XX(5, CLOSED_CONNECTION, CLOSED_CONNECTION) \ @@ -374,8 +377,6 @@ LLHTTP_EXPORT void llhttp_init(llhttp_t* parser, llhttp_type_t type, const llhttp_settings_t* settings); -#if defined(__wasm__) - LLHTTP_EXPORT llhttp_t* llhttp_alloc(llhttp_type_t type); @@ -400,8 +401,6 @@ int llhttp_get_status_code(llhttp_t* parser); LLHTTP_EXPORT uint8_t llhttp_get_upgrade(llhttp_t* parser); -#endif // defined(__wasm__) - /* Reset an already initialized parser back to the start state, preserving the * existing parser type, callback settings, user data, and lenient flags. */ @@ -556,6 +555,19 @@ void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled); */ void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled); +/* Enables/disables lenient handling of `Transfer-Encoding` header. + * + * Normally `llhttp` would error when a `Transfer-Encoding` has `chunked` value + * and another value after it (either in a single header or in multiple + * headers whose value are internally joined using `, `). + * This is mandated by the spec to reliably determine request body size and thus + * avoid request smuggling. + * With this flag the extra value will be parsed normally. + * + * **(USE AT YOUR OWN RISK)** + */ +void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled); + #ifdef __cplusplus } /* extern "C" */ #endif
README.md+31 −1 modified@@ -92,14 +92,22 @@ if (err == HPE_OK) { ``` For more information on API usage, please refer to [src/native/api.h](https://github.com/nodejs/llhttp/blob/main/src/native/api.h). +## Build Instructions + +Make sure you have [Node.js](https://nodejs.org/), npm and npx installed. Then under project directory run: + +```sh +npm install +make +``` + --- ### Bindings to other languages * Python: [pallas/pyllhttp][8] * Ruby: [metabahn/llhttp][9] - ### Using with CMake If you want to use this library in a CMake project you can use the snippet below. @@ -113,6 +121,28 @@ FetchContent_MakeAvailable(llhttp) target_link_libraries(${EXAMPLE_PROJECT_NAME} ${PROJECT_LIBRARIES} llhttp ${PROJECT_NAME}) ``` +## Building on Windows + +### Installation + +* `choco install git` +* `choco install node` +* `choco install llvm` (or install the `C++ Clang tools for Windows` optional package from the Visual Studio 2019 installer) +* `choco install make` (or if you have MinGW, it comes bundled) + +1. Ensure that `Clang` and `make` are in your system path. +2. Using Git Bash, clone the repo to your preferred location. +3. Cd into the cloned directory and run `npm install` +5. Run `make` +6. Your `repo/build` directory should now have `libllhttp.a` and `libllhttp.so` static and dynamic libraries. +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`. + +### A simple example on linking with the library: + +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`. + +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`. + #### LICENSE This software is licensed under the MIT License.
src/api.c+8 −0 modified@@ -253,6 +253,14 @@ void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) { } } +void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled) { + if (enabled) { + parser->lenient_flags |= LENIENT_TRANSFER_ENCODING; + } else { + parser->lenient_flags &= ~LENIENT_TRANSFER_ENCODING; + } +} + /* Callbacks */
src/http.c+2 −1 modified@@ -52,7 +52,8 @@ int llhttp__after_headers_complete(llhttp_t* parser, const char* p, return 2; } else if (parser->flags & F_TRANSFER_ENCODING) { if (parser->type == HTTP_REQUEST && - (parser->lenient_flags & LENIENT_CHUNKED_LENGTH) == 0) { + (parser->lenient_flags & LENIENT_CHUNKED_LENGTH) == 0 && + (parser->lenient_flags & LENIENT_TRANSFER_ENCODING) == 0) { /* RFC 7230 3.3.3 */ /* If a Transfer-Encoding header field
src/llhttp.c+762 −410 modified
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
15- github.com/advisories/GHSA-5689-v88g-g6rvghsaADVISORY
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/2ICG6CSIB3GUWH5DUSQEVX53MOJW7LYK/mitrevendor-advisory
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/QCNN3YG2BCLS4ZEKJ3CLSUT6AS7AXTH3/mitrevendor-advisory
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/VMQK5L5SBYD47QQZ67LEMHNQ662GH3OY/mitrevendor-advisory
- nvd.nist.gov/vuln/detail/CVE-2022-32213ghsaADVISORY
- www.debian.org/security/2023/dsa-5326ghsavendor-advisoryWEB
- cert-portal.siemens.com/productcert/pdf/ssa-332410.pdfghsaWEB
- github.com/nodejs/llhttp/commit/18a4afc7ffb4e49dc9e2daebc50588199a6d1dbbghsaWEB
- hackerone.com/reports/1524555ghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/2ICG6CSIB3GUWH5DUSQEVX53MOJW7LYKghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QCNN3YG2BCLS4ZEKJ3CLSUT6AS7AXTH3ghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/VMQK5L5SBYD47QQZ67LEMHNQ662GH3OYghsaWEB
- nodejs.org/en/blog/vulnerability/july-2022-security-releasesghsaWEB
- security.netapp.com/advisory/ntap-20220915-0001ghsaWEB
- nodejs.org/en/blog/vulnerability/july-2022-security-releases/mitre
News mentions
0No linked articles in our index yet.