
# CVE-2026-8161 개념 증명 익스플로잇 multiparty multipart 파서의 서비스 거부(DoS) 취약점으로, 프로토타입 오염(prototype pollution)으로 이어져 처리되지 않은 예외(uncaught exception)와 크래시를 유발함을 입증합니다.
CVE-2026-8161(Multiparty)의 개념 증명
[email protected] 및 이전 버전은 포착되지 않은 예외로 인한 서비스 거부(denial of service)에 취약합니다.
파서는 업로드된 필드와 파일을 일반 JavaScript 객체에 저장하며, 파서가 소유한 키와 상속된 객체 속성을 안전하게 구분하지 않습니다. 조작된 multipart 필드 이름은 파서가 예상치 못한 프로토타입 체인 값을 읽고 업로드를 처리하는 동안 충돌하도록 만들 수 있습니다.
취약한 버전의 multiparty를 통해 multipart 업로드를 수락하는 모든 서비스가 영향을 받을 수 있습니다.
이 문제는 fields와 files가 일반 JavaScript 객체이지만 사용자 제어 이름에 대한 안전한 키-값 맵처럼 사용되기 때문에 발생합니다.
var fieldsArray = fields[name] || (fields[name] = [])
fieldsArray.push(value)
var filesArray = files[name] || (files[name] = [])
filesArray.push(file)
문제는 fields[name]과 files[name]이 일반 JavaScript 속성 조회를 사용한다는 것입니다. 일반 객체의 경우 해당 조회는 객체 자체에 저장된 값만이 아니라 프로토타입 체인의 상속된 속성을 반환할 수 있습니다.
name이 __proto__인 경우 JavaScript는 프로토타입 체인을 통해 이를 확인하고 상속된 프로토타입 객체를 undefined 대신 반환할 수 있습니다. 해당 값은 truthy이므로 대체 할당이 건너뛰어지고 파서는 해당 필드에 대한 실제 배열을 생성하지 않습니다.
패치는 객체에 직접 속한 키만 신뢰하여 이 문제를 해결합니다:
var filesArray = Object.prototype.hasOwnProperty.call(files, name)
? files[name]
: undefined
그런 다음 파서는 저장된 값이 실제로 배열인 경우에만 추가하고, 그렇지 않으면 새 배열을 초기화합니다:
if (Array.isArray(filesArray)) {
filesArray.push(file)
} else {
files[name] = [file]
}
배열이 아닌 값에 대해 .push()가 호출되면 TypeError가 발생합니다. 이는 Multiparty의 비동기 파싱 흐름 내부에서 발생하므로 일반적인 호출자 측 오류 처리가 이를 포착하지 못해 예외가 프로세스를 중단시킬 수 있습니다.
Object.prototype.hasOwnProperty.call(...).mocklab 환경을 실행하고 두 대상 모두에 테스트 페이로드를 전송합니다:
docker compose up -d
python3 secdos.py -u http://localhost:8080/api/submit
python3 secdos.py -u http://localhost:8081/api/submit
취약한 대상은 충돌하여 [PASS]를 반환합니다. 패치된 대상은 요청을 안전하게 처리하고 [FAIL]을 반환합니다.
취약한 서버에 대해 다시 실행하는 경우 먼저 서버를 재시작하십시오
dockerfile에서 패치된 이미지를 빌드하려면 빌드 인수 PATCHED=1이 필요합니다