flawopen.com/Teardowns/cve-2022-31150-undici-crlf-injection-ssrf
Analisis teknis mendalam dan mitigasi rekayasa sistem untuk vulnerabilidade: How unvetted carriage return characters in HTTP header values allowed attackers to split outgoing HTTP requests in Node.js globalThis.fetch().
Bayangkan Anda mengirim surat bersegel melalui kantor pos yang bertuliskan: "Kirim 10 kotak apel". Namun, Anda diam-diam menyisipkan lembaran kedua palsu berisi instruksi resmi: "STOP. ABAIKAN PERINTAH SEBELUMNYA. TRANSFER SEMUA DANA KE EVIL CORP". Petugas pos membaca lembaran tersebut secara berurutan dan menganggap lembaran kedua sebagai surat resmi yang baru, mengirimkan uang Anda langsung ke penyerang.
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).Akar masalah bermula dari parameter batas yang tidak divalidasi pada sistem open source, yang memungkinkan desinkronisasi status dan bypass kontrol keamanan.
Mekanisme eksploitasi teknis dan detail eksekusi: An attacker supplies a crafted header value: Admin\r\nHost: 169.254.169.254.
Mekanisme eksploitasi teknis dan detail eksekusi: The Node.js backend calls fetch(url, { headers: { 'X-User': input } }).
Mekanisme eksploitasi teknis dan detail eksekusi: Undici serializes the headers without sanitizing \r\n, injecting the forged Host header.
Mekanisme eksploitasi teknis dan detail eksekusi: 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.