Home [Web] Prototype Pollution 간단 정리
Post
Cancel

[Web] Prototype Pollution 간단 정리

일주일 동안 우연치 않게 연속으로 Prototype Pollution에 대한 문제를 몇 개 풀어보았는데 글로 정리해야지를 실천하지 못하다가 오늘 적어봅니다…

Prototype


프로토타입(prototype)은 객체입니다. 자바스크립트의 모든 객체들은 최소 하나 이상의 다른 객체로 부터 상속을 받게되는데, 이때 상속되는 정보를 제공하는 객체를 프로토타입이라고 합니다. 쉽게 예시를 들면 알리오 올리오라는 객체가 있다면 이것의 프로토타입은 파스타(알리오올리오.prototype)가 될 수 있죠. 하지만 프로토타입을 가지지 않는 객체도 존재하는데요. 바로 최상단에 위치한다고 볼 수 있는 Object.prototype이 그렇습니다. 이 글에서 한가지 기억해둬야 할 것은 만약 아래에 있는 코드처럼 객체 리터럴의 형태로 객체를 생성하면 그 객체의 부모는 __proto__로 접근할 수 있고, 그 객체의 프로토타입은 Object.prototype이 된다는 것입니다.

1
2
const obj1 = {};
console.log(obj1.__proto__ === Object.prototype); // true

pasta


Prototype Chain


자바스크립트는 이처럼 프로토타입을 이용해서 상속을 표현하는데, 만약 어떤 속성을 객체에서 찾는데 그 속성이 없다면 프로토타입에서 속성을 검색합니다. 만약 거기서도 없다면 프로토타입의 프로토타입에서 검색을 하겠죠? 이런 특성을 Prototype Chain 이라고 합니다. 위 코드에서 우리가 obj1의 속성으로 toString 메서드를 정의하지 않아도 obj1.toString()을 불러올 수 있는 이유이기도 하죠. 이어서 설명하겠지만 Prototype ChainPrototype Pollution에 있어서 중요한 키포인트가 됩니다.

Prototype Pollution


그렇다면 이 글의 주인공인 Prototype Pollution이란 뭘까요? 말 그대로 프로토타입의 속성을 오염시켜 발생하는 취약점 입니다. 아래 4줄자리 코드가 위에서 말한 내용들을 대변하고 있습니다.

1
2
3
4
5
const obj1 = {};
obj1.__proto__.hoppi = 'polluted';
const obj2 = {};
console.log(obj2.hoppi); // polluted


또한 __proto__이라는 key를 통한 접근도 가능합니다. 같은 말을 반복하는 것이지만 사용자가 객체의 key를 설정할 수 있고 value에 대한 핉터링이 없으면 아래처럼 PP가 가능해집니다.

1
2
3
4
const obj1 = {};
obj1['__proto__']['is_admin'] = true;
const obj2 = {};
console.log(obj2.is_admin); // true


Mitigation


간단하게 예방하는 방법은 아래와 같습니다.

  • __proto__, prototype, constructor와 같은 키워드는 필터링
  • Object.freeze(Object.prototype)를 사용하여 프로토타입을 freeze

Conclusion


짧지만 굵게 Prototype Pollution에 대해서 적어봤습니다. 드림핵에서 적용해볼 수 있는 문제로는 NSS, Environment Pollution, filestorage가 있겠네요. 이미 PP에 대해서 검색해보신 분이면 알겠지만 구글에 좋은 자료들이 많이 넘쳐나기 때문에 오염이 발생할 수 있는 패턴과 더 자세한 설명은 레퍼런스를 참고하시면 되겠습니다.

Reference


[Tip] Intercept localhost web packet with Burp

[Webhacking.kr] sliping beauty

Comments powered by Disqus.