NodeJS - __proto__ & prototype Pollution
JavaScript의 객체
JavaScript의 객체는 본질적으로 속성이라고 하는 키-값 쌍의 컬렉션입니다. 객체는 Object.create
를 사용하여 인수로 null
을 전달하여 빈 객체를 생성할 수 있습니다. 이 방법을 사용하면 상속된 속성이 없는 객체를 생성할 수 있습니다.
자바스크립트의 함수와 클래스
자바스크립트에서 클래스와 함수는 밀접한 관련이 있으며, 함수는 종종 클래스의 생성자로 작동합니다. 자바스크립트는 네이티브 클래스 지원이 부족하지만, 생성자는 클래스 동작을 흉내 낼 수 있습니다.
자바스크립트의 프로토타입
자바스크립트는 런타임에서 프로토타입 속성을 수정, 추가 또는 삭제할 수 있습니다. 이 유연성은 클래스 기능을 동적으로 확장할 수 있게 합니다.
toString
및 valueOf
와 같은 함수는 그들의 동작을 변경하기 위해 수정될 수 있으며, 이는 자바스크립트의 프로토타입 시스템의 적응 가능성을 보여줍니다.
상속
프로토타입 기반 프로그래밍에서 속성/메서드는 클래스로부터 객체에게 상속됩니다. 이러한 클래스는 다른 클래스의 인스턴스에 속성/메서드를 추가하거나 빈 객체에 추가하여 생성됩니다.
주의할 점은 다른 객체들에게 프로토타입으로 작용하는 객체(예: myPersonObj
)에 속성이 추가될 때, 상속받는 객체들이 이 새로운 속성에 접근할 수 있다는 것입니다. 그러나 이 속성은 명시적으로 호출되지 않는 이상 자동으로 표시되지 않습니다.
__proto__ 오염
자바스크립트에서 프로토타입 오염 탐색
자바스크립트 객체는 키-값 쌍으로 정의되며, 자바스크립트 객체 프로토타입에서 상속됩니다. 이는 Object 프로토타입을 변경하면 환경 내의 모든 객체에 영향을 줄 수 있다는 것을 의미합니다.
다른 예제를 사용하여 설명해 봅시다:
객체 프로토타입에 접근하는 것이 가능합니다:
객체 프로토타입에 속성을 추가함으로써 모든 JavaScript 객체가 이러한 새로운 속성을 상속받게 됩니다:
프로토타입 오염
__proto__
사용이 제한된 시나리오에서 함수의 프로토타입을 수정하는 것이 대안입니다:
이는 Vehicle
생성자에서 생성된 객체에만 영향을 줍니다. beep
, hasWheels
, honk
, 그리고 isElectric
속성을 제공합니다.
자바스크립트 객체에 전역적으로 영향을 주는 두 가지 방법은 다음과 같습니다:
Object.prototype
을 직접 오염시키기:
자주 사용되는 구조체의 생성자 프로토타입을 오염시키기:
이러한 작업 이후에는 모든 JavaScript 객체가 goodbye
및 greet
메서드를 실행할 수 있습니다.
다른 객체 오염
클래스에서 Object.prototype으로
특정 객체를 오염시킬 수 있는 시나리오에서 Object.prototype
에 도달해야 하는 경우 다음과 같은 코드로 검색할 수 있습니다:
배열 요소 오염
JS에서 객체의 속성을 오염시킬 수 있는 것처럼, 배열을 오염시킬 수 있다면 배열의 값도 오염시킬 수 있다는 것을 유의하십시오. 이 값들은 인덱스에 의해 접근됩니다 (값을 덮어쓸 수 없으므로, 쓰이지만 쓰이지 않는 인덱스를 오염시켜야 합니다).
Html 요소 오염
JS를 통해 HTML 요소를 생성할 때 innerHTML
속성을 덮어쓰기하여 임의의 HTML 코드를 작성할 수 있습니다. 이 아이디어와 예시는 이 글에서 차용되었습니다.
예제
기본 예제
프로토타입 오염은 응용 프로그램에서 발생하는 결함으로 인해 Object.prototype
의 속성을 덮어쓸 수 있는 상황에서 발생합니다. 이는 대부분의 객체가 Object.prototype
에서 속성을 파생하기 때문에 발생합니다.
가장 쉬운 예는 확인될 객체의 정의되지 않은 속성에 값을 추가하는 것입니다.
만약 속성 admin
이 정의되지 않은 경우 PP를 남용하여 다음과 같이 True로 설정할 수 있습니다:
이 메커니즘은 특정 입력을 통제하는 공격자가 응용 프로그램의 모든 객체의 프로토 타입을 수정할 수 있도록 속성을 조작하는 것을 포함합니다. 이 조작은 일반적으로 __proto__
속성을 설정하여 이루어지며, JavaScript에서는 이것이 객체의 프로토 타입을 직접 수정하는 것과 동의어입니다.
이 공격이 성공적으로 실행될 수 있는 조건은 특정 연구에서 설명된 대로 다음과 같습니다:
재귀적 병합 수행.
경로를 기반으로 속성 정의.
객체 복제.
함수 재정의
Proto Pollution to RCE
pagePrototype Pollution to RCE기타 페이로드:
클라이언트 측 프로토타입 오염으로 XSS
pageClient Side Prototype PollutionCVE-2019–11358: jQuery $ .extend를 통한 프로토타입 오염 공격
자세한 내용은 이 기사를 확인하십시오 jQuery에서 $ .extend
함수는 깊은 복사 기능이 부적절하게 사용되면 프로토타입 오염으로 이어질 수 있습니다. 이 함수는 일반적으로 객체 복제나 기본 객체에서 속성을 병합하는 데 사용됩니다. 그러나 잘못 구성된 경우, 새 객체를 위해 의도된 속성이 대신 프로토타입에 할당될 수 있습니다. 예를 들어:
이 취약점은 CVE-2019–11358로 식별되었으며, 깊은 복사가 원치 않게 프로토타입을 수정할 수 있어 isAdmin
과 같은 속성이 적절한 존재 확인 없이 확인되면 무단 관리자 액세스와 같은 잠재적 보안 위험으로 이어질 수 있음을 보여줍니다.
CVE-2018–3721, CVE-2019–10744: 로다시를 통한 프로토타입 오염 공격
Lodash는 유사한 프로토타입 오염 취약점(CVE-2018–3721, CVE-2019–10744)을 겪었습니다. 이러한 문제는 버전 4.17.11에서 해결되었습니다.
CVE가 포함된 또 다른 자습서
프로토타입 오염 감지 도구
Server-Side-Prototype-Pollution-Gadgets-Scanner: 웹 애플리케이션에서 서버 측 프로토타입 오염 취약점을 감지하고 분석하기 위해 설계된 Burp Suite 확장 프로그램. 이 도구는 잠재적인 프로토타입 오염 문제를 식별하기 위해 요청을 스캔하는 프로세스를 자동화합니다. 특히 Node.js 라이브러리에 중점을 둔 알려진 가젯을 악용합니다.
server-side-prototype-pollution: 이 확장 프로그램은 서버 측 프로토타입 오염 취약점을 식별합니다. 이는 서버 측 프로토타입 오염에서 설명된 기술을 사용합니다.
NodeJS에서 AST 프로토타입 오염
NodeJS는 템플릿 엔진 및 TypeScript와 같은 기능을 위해 JavaScript에서 추상 구문 트리(AST)를 광범위하게 활용합니다. 이 섹션에서는 Handlebars와 Pug와 같은 템플릿 엔진에서 프로토타입 오염과 관련된 취약점을 탐구합니다.
Handlebars 취약점 분석
Handlebars 템플릿 엔진은 프로토타입 오염 공격에 취약합니다. 이 취약점은 javascript-compiler.js
파일 내의 특정 함수에서 발생합니다. 예를 들어, appendContent
함수는 pendingContent
가 존재하는 경우 이를 연결하고, pushSource
함수는 소스를 추가한 후 pendingContent
를 undefined
로 재설정합니다.
악용 과정
악용은 Handlebars에 의해 생성된 AST(추상 구문 트리)를 활용하여 다음 단계를 따릅니다:
파서 조작: 먼저, 파서는
NumberLiteral
노드를 통해 값이 숫자임을 강제합니다. 프로토타입 오염을 통해 이를 우회하여 숫자가 아닌 문자열을 삽입할 수 있습니다.컴파일러 처리: 컴파일러는 AST 객체 또는 문자열 템플릿을 처리할 수 있습니다.
input.type
이Program
인 경우 입력이 사전 구문 분석된 것으로 처리되어 악용될 수 있습니다.코드 삽입:
Object.prototype
을 조작하여 템플릿 함수에 임의의 코드를 삽입할 수 있으며, 이는 원격 코드 실행으로 이어질 수 있습니다.
Handlebars 취약점 악용을 보여주는 예시:
이 코드는 공격자가 Handlebars 템플릿에 임의의 코드를 삽입할 수 있는 방법을 보여줍니다.
외부 참조: 'flat' 라이브러리와 관련된 프로토타입 오염 문제가 발견되었습니다. 자세한 내용은 다음을 참조하십시오: GitHub의 이슈.
외부 참조: 'flat' 라이브러리에서 발견된 프로토타입 오염과 관련된 이슈: 이슈
Python에서 프로토타입 오염 취약점의 예시:
Pug 취약점
Pug, 또 다른 템플릿 엔진,는 프로토타입 오염과 유사한 위험에 직면합니다. 자세한 정보는 Pug에서의 AST Injection에 대한 토론에서 확인할 수 있습니다.
Pug에서의 프로토타입 오염 예시:
예방 조치
프로토타입 오염의 위험을 줄이기 위해 아래에 나열된 전략들을 사용할 수 있습니다:
객체 불변성:
Object.freeze
를 적용하여Object.prototype
을 불변하게 만들 수 있습니다.입력 유효성 검사: JSON 입력은 응용 프로그램의 스키마에 엄격히 대조되어야 합니다.
안전한 병합 함수: 재귀적 병합 함수의 안전하지 않은 사용은 피해야 합니다.
프로토타입 없는 객체:
Object.create(null)
을 사용하여 프로토타입 속성이 없는 객체를 생성할 수 있습니다.Map 사용:
Object
대신에 키-값 쌍을 저장하기 위해Map
을 사용해야 합니다.라이브러리 업데이트: 정기적으로 라이브러리를 업데이트하여 보안 패치를 통합할 수 있습니다.
린터 및 정적 분석 도구: ESLint와 같은 적절한 플러그인을 사용하여 프로토타입 오염 취약점을 감지하고 방지하는 데 도움이 되는 도구를 사용해야 합니다.
코드 리뷰: 프로토타입 오염과 관련된 잠재적 위험을 식별하고 해결하기 위해 철저한 코드 리뷰를 시행해야 합니다.
보안 교육: 개발자들에게 프로토타입 오염의 위험과 안전한 코드 작성을 위한 모범 사례에 대해 교육해야 합니다.
신중한 라이브러리 사용: 제3자 라이브러리 사용 시 신중해야 합니다. 그들의 보안 포지션을 평가하고 특히 객체 조작과 관련된 코드를 검토해야 합니다.
런타임 보호: 보안 중심 npm 패키지를 사용하여 프로토타입 오염 공격을 감지하고 방지할 수 있는 런타임 보호 메커니즘을 도입해야 합니다.
참고 자료
Last updated