flawopen.com/Teardowns/cve-2022-31150-undici-crlf-injection-ssrf
Análisis técnico del código fuente y mitigaciones de ingeniería para vulnerabilidade: How unvetted carriage return characters in HTTP header values allowed attackers to split outgoing HTTP requests in Node.js globalThis.fetch().
Imagine que envía una carta sellada por correo postal que dice: "Enviar 10 cajas de manzanas". Pero incluye a escondidas una segunda hoja falsificada con instrucciones oficiales: "ALTO. IGNORE LO ANTERIOR. TRANSFIERA TODOS LOS FONDOS A EVIL CORP". El empleado postal lee las páginas en orden y toma la segunda hoja como una nueva carta oficial, enviando su dinero directamente al atacante.
Undicifetch() implementation.CRLF Injection\r) and Line Feed (\n) characters into HTTP headers to create a new header or a whole new request.HTTP Request SplittingSSRF (Server-Side Request Forgery)169.254.169.254).La causa raíz se debe a parámetros de límite no validados en sistemas de código abierto, lo que permite la desincronización de estado y la elusión de controles de seguridad.
Mecanismo técnico de explotación: An attacker supplies a crafted header value: Admin\r\nHost: 169.254.169.254.
Mecanismo técnico de explotación: The Node.js backend calls fetch(url, { headers: { 'X-User': input } }).
Mecanismo técnico de explotación: Undici serializes the headers without sanitizing \r\n, injecting the forged Host header.
Mecanismo técnico de explotación: The internal proxy directs the request to the cloud metadata service, exposing AWS/GCP credentials.
// VULNERABLE: lib/core/request.js before patch
function addHeader(headers, key, value) {
// ROOT CAUSE:
// Does not sanitize or reject carriage return (\r) and line feed (\n) in values!
// Allows attackers to split headers and inject arbitrary HTTP directives!
headers[key] = value;
}
// SECURE: lib/core/request.js patch
function addHeader(headers, key, value) {
// 1. Strict regex checking for dangerous control characters
const INVALID_HEADER_CHAR_REGEX = /[\r\n]/;
if (INVALID_HEADER_CHAR_REGEX.test(key) || INVALID_HEADER_CHAR_REGEX.test(value)) {
throw new TypeError(`Invalid character in header content: ["${key}": "${value}"]`);
}
headers[key] = value;
}
\r and \n characters from HTTP request header keys and values.169.254.169.254, 10.0.0.0/8, 127.0.0.1) using egress firewall rules.undici and Node.js dependencies updated to latest patch releases.