반응형
Prototype Pollution
공격자가 Object.prototype 같은 전역(공통) 프로토타입에 임의의 속성을 추가/변조해서, 이후 생성되는 많은 객체들이 그 속성을 상속받도록 만드는 취약점
JS는 객체에서 속성을 찾을 때 없으면 프로토타입 체인을 따라 올라가며 찾는데, 이때 전역 프로토타입(Object.prototype)이 오염되면, 앱 전체 로직이 예상 밖으로 바뀔 수 있다.
프로토 타입을 오염시키면
- 모든 객체가 영향받음
: 새로 만들어지는 모든 객체에 악의적인 속성이 추가됨 - 권한 우회
: 접근 제어 로직을 우회할 수 있음 - 원격 코드 실행
: 특정 조건에서 임의의 코드를 실행할 수 있음 - 서비스 거부
: 애플리케이션을 중단시킬 수 있음
Prototype Pollution 발생 원리
기본 메커니즘
Prototype Pollution은 주로 안전하지 않은 객체 병합이나 사용자 입력을 객체 키로 사용할 때 발생한다.
// 위험: 사용자 입력을 그대로 사용
function merge(target, source) {
for (let key in source) {
target[key] = source[key];
}
return target;
}
// 악의적인 페이로드
const maliciousInput = JSON.parse('{"__proto__": {"isAdmin": true}}');
const user = {};
merge(user, maliciousInput);
// 이제 모든 객체가 isAdmin 속성을 가지게 됨!
const newUser = {};
console.log(newUser.isAdmin); // true (오염됨!)
const anotherUser = {};
console.log(anotherUser.isAdmin); // true (이것도 오염됨!)
공격 벡터 (Attack Vectors)
1. __proto__사용
// 공격 전
const obj = {};
console.log(obj.polluted); // undefined
// 공격: __proto__를 통한 오염
const payload = {
"__proto__": {
"polluted": "YES!"
}
};
function unsafeMerge(target, source) {
for (let key in source) {
if (typeof source[key] === 'object' && source[key] !== null) {
target[key] = unsafeMerge(target[key] || {}, source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
unsafeMerge({}, payload);
// 공격 후 - 모든 객체가 오염됨
const newObj = {};
console.log(newObj.polluted); // "YES!" (위험!)
const test = {};
console.log(test.polluted); // "YES!" (이것도!)
- source[key] = {"polluted" : "YES!"}로 객체
- source[key] = "YES"로 문자열 else로 감
- target[key]가 있으면 그걸 쓰고, 없으면 빈 객체 {} 만들어서 그 안에 source[key] 객체를 재귀적으로 병합한 결과를 target[key]에 넣음
2. constructor.prototype 사용
// 공격 전
const obj = {};
console.log(obj.hacked); // undefined
// 공격: constructor.prototype를 통한 오염
const payload = {
"constructor": {
"prototype": {
"hacked": true
}
}
};
function vulnerableAssign(target, source) {
for (let key in source) {
target[key] = source[key];
}
}
vulnerableAssign({}, payload);
// 공격 후
const newObj = {};
console.log(newObj.hacked); // true (오염됨!)
3. 배열 인덱스를 통한 오염
// 취약한 배열 처리
function vulnerableArrayMerge(target, source) {
for (let key in source) {
target[key] = source[key];
}
return target;
}
// 공격
const arr = [];
vulnerableArrayMerge(arr, {
"__proto__": {
"isEvil": true
}
});
// 결과
const newArray = [];
console.log(newArray.isEvil); // true
const normalObj = {};
console.log(normalObj.isEvil); // true
방어 기법
1. 위험한 키 차단
: __proto__, constructor, prototype 키를 차단한다.
2. Object.create(null) 사용
: 프로토 타입이 없는 순수 객체를 생성
3. Object.freeze() 사용
: 프로토타입을 동결하여 수정을 방지
반응형
'Web Study' 카테고리의 다른 글
| AWK Code Injection (0) | 2026.02.20 |
|---|---|
| CVE-2022-29078 (0) | 2026.02.19 |
| CVE-2025-29927 (0) | 2026.01.13 |
| XS - Search (1) | 2026.01.07 |
| XXE Injection (0) | 2026.01.04 |