logo
Published on

Prototype Pollution

Prototype Pollution은 js를 사용하는 서비스에서 심심치 않게 발생하는 취약점이다.

What is Prototype?

Javascript는 prototype을 기반으로 한 언어이다. javascript에서의 모든 객체는 자신의 부모 역할을 하는 객체(prototype)과 연결이 되어 있다. 생성되는 모든 객체는 prototype 객체에 접근을 할 수 있고, 동적으로 멤버를 추가할 수 있다.

특정 객체에서 속성이나 메소드에 접근할 때, JS 엔진에서 먼저 객체 안에 해당 속성이나 메소드를 가지고 있는지를 파악한다. 만약 갖고 있지 않다면, 부모 역할을 하는 상위 객체를 향해 접근하고 있는 속성이나 메소드가 나올 때까지 거슬러 올러가 찾는다.

모든 prototype은 객체(Object)이기 때문에, 마지막 Object.prototype까지 찾고, 찾지 못한다면 undefined를 반환한다.

Prototype Pollution

Prototype Pollution 취약점은 위에서 설명한 javascript의 prototype을 말 그대로 오염(pollution)시키는 공격을 의미한다.

만약 유저가 특정 객체의 속성이나 메소드를 지정해서 값을 저장할 수 있다면, 해당 취약점이 발생할 수 있다.

예시로 다음과 같은 코드를 보자.

let a ={}
a['__proto__']['polluted'] = 'hello'

let b = {}

console.log(a)
console.log(b)
console.log(b.polluted)

위와 같은 코드를 실행하면 결과는 다음과 같다.

{}
{}
hello

위와 같이 a의 __proto__에 접근하여 객체의 프로토타입에 접근하여 polluted 속성을 추가할 수 있다.

polluted 속성은 객체의 프로토타입에 추가되었기 때문에, a와 b를 출력해도 아무런 결과가 뜨지 않는 것을 볼 수 있다.

그러나 b.polluted를 통해서 polluted 속성에 접근하면, b에는 존재하지 않는 속성이기 때문에 js 엔진은 b의 상위 객체에 접근하게 된다.

결국 a의 부모(원형) 오브젝트와 b의 부모(원형) 오브젝트는 동일하기 때문에, a에서 접근한 __proto__polluted에 접근하게 되어 'hello'를 출력하게 된다.

이를 이용하여 JS를 이용하여 동작하는 다양한 웹 어플리케이션에 취약점이 발생할 수 있다.

TBA