Prototype 이란
자바스크립트에서 모든 객체들이 메서드와 속성을 상속받기 위한 객체
객체를 생성할 때 기본적으로 상속되며 여러 메소드를 포함한다. 새로운 인스턴스가 생성될 때, 생성된 인스턴스는
상위 객체의 프로토타입을 상속받아 생성되고, 인스턴스의 상위 객체 또한 더 위의 상위 객체로부터 프로토타입
객체를 상속받아 생성되는데 이렇게 프로토타입 객체를 상속받고 또 상속받는 것을 '프로토타입 체인'이라고 한다.
prototype-pollutions이란
North Sec 2018, 보안 연구자 Olivier Arteau의 “Prototype pollution attacks in NodeJS applications“라는 발표를 했다.
공격자가 JS언어 고유의 프로토타입 체인 동작 원리를 이용해 웹 서버를 공격하는 방법을 prototype-pollutions이라 한다.
상위 객체에서 상속되어 오는 프로토타입을 사용자가 접근하여 내용을 변경하거나 임의의 내용을 추가하면 그것은 하위 객체에도 그대로 상속되게 된다.
이러한 성질을 이용해여 객체 리터럴의 __proto__는 Object.prototype과 같다는 것을 이용해 다른 객체 속성에 영향을 주는 방식이다.
function Person(height,weight){
height:height;
weight:weight;
};
a = new Person();
a.__proto__.weight = 123;
console.log(a.weight); //123
b = new Person();
console.log(b.weight); //123
//a의 prototype 객체 조작으로 아무 관계없는 b의 속성값 변경
위 코드를 보면 Person라는 object함수를 선언하면 Prototype.Object가 같이 선언된다.
이렇게 생성된 함수는 prototype이라는 속성을 통해 Prototype Object에 접근할 수 있고
Prototype Object의 속성 중 __proto__를 통해 함수 객체와 연결되어 있다.
그다음 a라는 객체를 생성하면 a의 __proto__속성은 Person Prototype에 연결되고
다른 b라는 객체를 생성한 후 __proto__ 값을 조작할 수 있다면 a, b의 속성값들을 변경할 수 있다.
논문에 나온 Prototype Pollution이 일어나는 3가지 경우는
속성 설정, 객체 병합, 객체 복사가 있다.
속성 설정
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__.polluted", 1);
const obj2 = {};
console.log(obj2.polluted); // 1
객체 병합
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__":{"polluted":1}}');
merge(obj1, obj2);
const obj3 = {};
console.log(obj3.polluted); // 1
객체 복사
function clone(obj) {
return merge({}, obj);
}
const obj1 = JSON.parse('{"__proto__":{"polluted":1}}');
const obj2 = clone(obj1);
const obj3 = {};
console.log(obj3.polluted); // 1
'Web > 개념정리' 카테고리의 다른 글
[개념정리] Mutation XSS (0) | 2024.06.25 |
---|---|
[개념정리] Dompurify (0) | 2024.06.23 |
[개념정리] PHP Deserialization 취약점 (0) | 2024.05.26 |
[개념정리] case mapping collision (0) | 2024.02.29 |
[개념정리] Click jacking (0) | 2024.01.05 |