Prototype Pollution ??
Prototype Pollution은 Javascript 처리 로직의 문제로 Object의 prototype을 수정할 수 있을 때 발생합니다. 방법에는 여러 가지 있겠지만 가장 기본은 객체 리터럴의 __proto__는 Object.prototype과 같다는 것을 이용해 다른 객체 속성에 영향을 주는 방식입니다.
공격방법
일반적으로 아래 두가지 객체를 이용하여 공격에 활용합니다.
- Object.proto
- Object.constructor.prototype
Set Property 방식
사용자가 통제할 수 있는 입력 구간에서 값을 읽어 Property에 설정하는 로직이 있는 경우 proto 와 같은 property를 변경하여 공격가능합니다.
function isObject(obj) {
return obj !== null && typeof obj === 'object';
}
function setValue(obj, key, value) {
const keylist = key.split('.');
const e = keylist.shift();
if (keylist.length > 0) {
if (!isObject(obj[e])) obj[e] = {};
setValue(obj[e], keylist.join('.'), value);
} else {
obj[key] = value;
return obj;
}
}
const obj1 = {};
setValue(obj1, "__proto__.hacked", "test");
const obj2 = {};
console.log(obj2.hacked); // test
Object Merge 방식
Object 2개를 병합하는 merge 형태의 경우도 Prototype Pollution 공격이 가능합니다.
function merge(a, b) {
for (let key in b) {
if (isObject(a[key]) && isObject(b[key])) {
merge(a[key], b[key]);
} else {
a[key] = b[key];
}
}
return a;
}
const obj1 = {a: 1, b:2};
const obj2 = JSON.parse('{"__proto__":{"hacked":"test"}}');
merge(obj1, obj2);
const obj3 = {};
console.log(obj3.hacked); // test
Object Copy 방식
function clone(obj) {
return merge({}, obj);
}
const obj1 = JSON.parse('{"__proto__":{"hacked":"test"}}');
const obj2 = clone(obj1);
const obj3 = {};
console.log(obj3.polluted); // test
Prototype Pollution 조치방안
이 공격을 방지하는 대책으로 다음 세 가지 방법이 있습니다.
- Object.freeze : Object.prototype이나 Object를 freeze하여 변경을 불가능하게 하는 방법입니다. 부작용으로 정상적인 모듈임에도 이 조치로 동작하지 않을 수도 있습니다.
- JSON schema : avj 모듈 등을 사용해 JSON을 검증합니다.
- Map : key / value를 저장하는데 객체를 사용하지 않고 Map을 사용합니다. 단, ES5 이전 환경에서는 사용할 수 없습니다.
- Update JS Library : JS 라이브러리에 Prototype Pollution 취약점이 발견되는 경우가 많기 때문에 이러한 경우 가급적 패치 버전, 최신 버전으로 업데이트하는 것이 좋습니다.
- Recursive merge 사용 금지
- prototype 사용 X: Object.create(null)와 같이 prototype이 없는 object를 이용하여 pollution을 방지할 수 있습니다.
출처 및 참고자료
https://blog.coderifleman.com/2019/07/19/prototype-pollution-attacks-in-nodejs/ https://www.hahwul.com/cullinan/prototype-pollution/