
tough-cookie 패키지의 프로토타입 오염 취약점(CVE-2023-26136) 수정
프로토타입 오염(Prototype pollution)은 공격자가 전역 객체 프로토타입에 임의의 속성을 추가할 수 있게 하는 JavaScript 취약점으로, 이후 사용자 정의 객체가 해당 속성을 상속할 수 있습니다. 프로토타입 오염 소스는 프로토타입 객체에 임의의 속성을 추가할 수 있게 하는 사용자 제어 가능한 입력입니다. 가장 일반적인 소스는 다음과 같습니다.
URL JSON 웹 메시지
tough-cookies 패키지(v2.5.0)의 경우 첫 번째인 URL이 더 관련이 있습니다. 다음과 같이 발생합니다.
다음은 요청 예시입니다.
https://vulnerable-website.com/?__proto__[badProperty]=payload
쿼리 문자열을 키:값 쌍으로 분해할 때 URL 파서는 __proto__를 임의의 문자열로 해석할 수 있습니다.
어떤 시점에서 재귀적 병합 작업이 다음에 해당하는 명령문을 사용하여 evilProperty의 값을 할당할 수 있습니다.
targetObject.__proto__.badProperty = 'payload';
__proto__는 JavaScript에서 특별한 용도로 사용됩니다. 알다시피, 어떤 객체에서 특정 속성 P1을 찾지 못하면 해당 객체의 프로토타입에서 검색됩니다.
예제
function myClass() {
this.P1 = 'value';
}
let mc = new myClass();
console.log(mc.P1); //Value
console.log(mc.P2); //Undefined
mc.__proto__.P2 = 'value2';
let mc2 = new myClass();
console.log(mc.P2); //value2
__proto__를 변경한 후에는 myClass로 생성된 모든 인스턴스가 P2 속성을 갖게 됩니다.
tough-cookies 패키지(v2.5.0)에서는 이 프로토타입 오염 취약점을 다음 코드 조각에서 확인할 수 있습니다.
await new Promise((resolve, reject) => {
cookiejar.setCookie(
"Slonser=polluted; Domain=__proto__; Path=/notauth",
"https://__proto__/admin",
{ loose: true },
(err, cookie) => {
if (err) {
reject(err);
} else {
resolve(cookie);
}
}
);
});
CookieJar 클래스는 기본적으로 저장소로 MemoryCookieStore를 사용한다는 것이 발견되었습니다. 그리고 MemoryCookieStore의 여러 메서드에서 객체가 다음과 같이 초기화됩니다.
this.idx = {};
이는 __proto__를 통해 this.idx 프로토타입에 (문제가 될 수 있는) 값이 있는 속성을 추가할 수 있음을 의미합니다. 이를 방지하기 위해 여러 곳에서 초기화를 다음과 같이 변경했습니다.
this.idx = Object.create(null);
이는 프로토타입이 없는 빈 객체를 생성합니다. 수정을 검증하는 memstore_vulnerability_fix_test.js 테스트가 추가되었습니다.