Prototype Pollution: JS의 숨겨진 취약점
JavaScript의 prototype 체인을 오염시켜 앱 전체 동작을 바꾸는 공격 기법이다. 이름은 생소해도, 실전 CTF와 Bug Bounty에서 꽤 자주 등장한다.
원리
JS에서 모든 객체는 __proto__를 통해 상위 프로토타입을 참조한다.
const obj = {};
obj.__proto__.isAdmin = true;
const newObj = {};
console.log(newObj.isAdmin); // true ← 오염됨
obj.__proto__를 건드리면 Object.prototype 자체가 변조되어, 이후 생성되는 모든 객체에 영향을 준다.
공격 시나리오
1. 권한 우회
// 서버 코드 (Express)
if (req.user.isAdmin) { ... }
// 공격 payload (JSON merge 취약점)
{ "__proto__": { "isAdmin": true } }
lodash.merge, jquery.extend 같은 deep merge 함수들이 대표적인 진입점이다.
2. RCE로의 확장
Node.js 환경에서 child_process 관련 옵션이 prototype에 주입되면 Remote Code Execution까지 이어질 수 있다.
// 특정 라이브러리에서 실행 옵션을 prototype에서 읽는 경우
{ "__proto__": { "shell": "bash", "env": { "NODE_OPTIONS": "--inspect=0.0.0.0" } } }
탐지 & 방어
탐지:
Object.prototype에 예상치 못한 속성이 생겼는지 주기적 체크JSON.parse후__proto__,constructor키 필터링
방어:
Object.create(null)— prototype 없는 순수 객체 사용Object.freeze(Object.prototype)— prototype 동결- 신뢰할 수 없는 입력에 deep merge 금지
CTF 팁
Prototype Pollution 문제가 나오면 __proto__, constructor.prototype 두 경로를 모두 시도해보자. 라이브러리 버전을 확인하고 알려진 CVE를 체크하는 것도 필수다.
lodash < 4.17.19, jquery < 3.4.0 — 대표적인 취약 버전
작은 객체 하나가 앱 전체를 흔드는 게 Prototype Pollution의 묘미다. 🥞