시스템아 미안해

Chapter 5 - Item 44. null 프로토타입을 사용해서 프로토타입의 오염 방지하라 본문

책/Effective JavaScript

Chapter 5 - Item 44. null 프로토타입을 사용해서 프로토타입의 오염 방지하라

if else 2025. 8. 11. 08:55

자바스크립트 객체는 기본적으로 Object.prototype을 상속받는다.

이 말은, 모든 객체가 공통된 부모의 속성을 공유한다는 뜻이다.

 

문제는 프로토타입 오염(Prototype Pollution) 이다.

누군가 Object.prototype에 속성을 추가하면,

그 속성이 모든 객체에 자동으로 나타난다.

Object.prototype.hacked = true;

const user = {name: "AJ"};
console.log(user.hacked); // true (원래 없던 속성이 갑자기 생김)

이는 보안 취약점으로 이어질 수 있다.

 

 

책에서는 프로토타입이 없는 객체를 사용하라고 권장한다.

Object.create(null)을 사용하면 아예 Object.prototype이 없다.

const safeObj = Object.create(null);
safeObj.name = "AJ";
console.log(safeObj.hacked); // undefined

이렇게 하면 외부에서 프로토타입을 건드려도 영향이 없다.

 

 


 

 

 

ES6 이후에도 여전히 Object.create(null)이 핵심 방어 수단이다. 다만 ES6에서는 Map이 있어서, 애초에 프로토타입 오염 가능성이 없는 자료구조를 선택하는 게 안전하다.

Map은 키-값 저장 구조일 뿐, 프로토타입 체인을 사용하지 않기 때문이다.

서버 코드에서 Object.assign으로 사용자 입력을 병합할 땐 특히 주의하자.

// 취약 예시
const config = {};
Object.assign(config, userInput); // userInput이 __proto__를 포함하면 프로토타입 오염

// 안전 예시
const config = Object.create(null);
Object.assign(config, userInput); // 프로토타입 없음, 안전

 

 

 

  • 보안이 중요한 환경(서버, DB 매핑, 설정 객체)에선 무조건 Object.create(null) 또는 Map 사용.
  • 외부 데이터를 객체로 병합하기 전에는 __proto__, constructor 같은 키를 필터링.
  • {}는 빠르지만, 보안 리스크가 있는 상황에서는 절대 사용하지 말 것.