Back
Featured image of post Prototype Pollution 취약점

Prototype Pollution 취약점

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 조치방안

이 공격을 방지하는 대책으로 다음 세 가지 방법이 있습니다.

  1. Object.freeze : Object.prototype이나 Object를 freeze하여 변경을 불가능하게 하는 방법입니다. 부작용으로 정상적인 모듈임에도 이 조치로 동작하지 않을 수도 있습니다.
  2. JSON schema : avj 모듈 등을 사용해 JSON을 검증합니다.
  3. Map : key / value를 저장하는데 객체를 사용하지 않고 Map을 사용합니다. 단, ES5 이전 환경에서는 사용할 수 없습니다.
  4. Update JS Library : JS 라이브러리에 Prototype Pollution 취약점이 발견되는 경우가 많기 때문에 이러한 경우 가급적 패치 버전, 최신 버전으로 업데이트하는 것이 좋습니다.
  5. Recursive merge 사용 금지
  6. 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/

comments powered by Disqus