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 소스 코드 심층 기술 분석 및 시스템 보안 강화 가이드: 취약점 근본 원인과 패치 메커니즘 분석.

💡 알기 쉬운 설명 (ELI5)

우체국을 통해 "사과 10상자를 배송하라"는 밀봉된 편지를 보낸다고 상상해 보십시오. 하지만 편지봉투 안에 "중단. 이전 명령 무시. 전액을 공격자 조직으로 이체하라"는 위조된 두 번째 공식 서류를 몰래 끼워 넣습니다. 우체국 직원이 서류를 순서대로 읽다가 두 번째 서류를 완전히 새로운 공식 편지로 처리하여 자금이 공격자에게 그대로 송금됩니다.

핵심 개념 및 용어

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).

근본 원인 분석 (Root Cause)

근본 원인은 오픈 소스 시스템의 검증되지 않은 경계 매개변수로 인해 상태 비동기화 및 보안 제어 우회가 발생한 데 있습니다.

단계별 공격 실행 흐름

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;
}

엔지니어링 및 시스템 보안 강화 체크리스트

출처