flawopen.com/Teardowns/cve-2022-31150-undici-crlf-injection-ssrf

● CVE-2022-31150 · CVSS 6.5 · Средний
Исследования · FlawOpen

Технический разбор: CVE-2022-31150: Node.js Undici CRLF Injection & SSRF Teardown

Технический анализ исходного кода и защитные инженерные меры для vulnerabilidade: How unvetted carriage return characters in HTTP header values allowed attackers to split outgoing HTTP requests in Node.js globalThis.fetch().

💡 Простыми словами (ELI5)

Представьте, что вы отправляете запечатанное письмо по почте с текстом: "Отправить 10 ящиков яблок". Однако вы незаметно вкладываете второй поддельный официальный лист: "СТОП. ИГНОРИРОВАТЬ ПРЕДЫДУЩЕЕ. ПЕРЕВЕСТИ ВСЕ СРЕДСТВА В EVIL CORP". Почтовый клерк читает страницы по порядку и воспринимает второй лист как новое официальное письмо, переводя ваши деньги напрямую злоумышленнику.

Ключевые понятия и термины

Undici
The official next-generation HTTP/1.1 client for Node.js, powering the global fetch() implementation.
CRLF Injection
Injecting Carriage Return (\r) and Line Feed (\n) characters into HTTP headers to create a new header or a whole new request.
HTTP Request Splitting
A vulnerability where an attacker splits a single outgoing HTTP connection into two separate requests.
SSRF (Server-Side Request Forgery)
Coercing a backend server to issue unauthorized requests to internal cloud metadata APIs (169.254.169.254).

Анализ первопричины

Основная причина заключается в невалидированных граничных параметрах в системах с открытым исходным кодом, что приводит к рассинхронизации состояний и обходу средств безопасности.

Пошаговый сценарий атаки

Step 1

Этап атаки: Input Submission

Технический механизм эксплуатации уязвимости: An attacker supplies a crafted header value: Admin\r\nHost: 169.254.169.254.

Step 2

Этап атаки: Application Issues Fetch

Технический механизм эксплуатации уязвимости: The Node.js backend calls fetch(url, { headers: { 'X-User': input } }).

Step 3

Этап атаки: Header Splitting in Undici

Технический механизм эксплуатации уязвимости: Undici serializes the headers without sanitizing \r\n, injecting the forged Host header.

Step 4

Эксфильтрация данных(Cloud Metadata Exfiltration)

Технический механизм эксплуатации уязвимости: The internal proxy directs the request to the cloud metadata service, exposing AWS/GCP credentials.

Исходный код: Уязвимый vs Защищённый вариант

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
// 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;
}

Чек-лист по защите системы для инженеров

Источники