NodeJS - __proto__ & prototype Pollution
JavaScript의 객체
JavaScript의 객체는 본질적으로 속성으로 알려진 키-값 쌍의 모음입니다. 객체는 Object.create
를 사용하여 null
을 인수로 전달하여 빈 객체를 생성할 수 있습니다. 이 방법은 상속된 속성이 없는 객체를 생성할 수 있게 해줍니다.
빈 객체는 빈 사전과 유사하며, {}
로 표현됩니다.
JavaScript의 함수와 클래스
JavaScript에서 클래스와 함수는 밀접하게 연결되어 있으며, 함수는 종종 클래스의 생성자로 사용됩니다. JavaScript는 기본적인 클래스 지원이 없지만, 생성자는 클래스 동작을 모방할 수 있습니다.
Prototypes in JavaScript
JavaScript는 런타임에 프로토타입 속성을 수정, 추가 또는 삭제할 수 있습니다. 이 유연성은 클래스 기능의 동적 확장을 가능하게 합니다.
toString
및 valueOf
와 같은 함수는 그 동작을 변경하도록 수정될 수 있으며, 이는 JavaScript의 프로토타입 시스템의 적응 가능한 특성을 보여줍니다.
Inheritance
프로토타입 기반 프로그래밍에서 속성/메서드는 클래스에서 객체로 상속됩니다. 이러한 클래스는 다른 클래스의 인스턴스나 빈 객체에 속성/메서드를 추가하여 생성됩니다.
다른 객체의 프로토타입 역할을 하는 객체(예: myPersonObj
)에 속성이 추가되면, 상속받는 객체는 이 새로운 속성에 접근할 수 있습니다. 그러나 이 속성은 명시적으로 호출되지 않는 한 자동으로 표시되지 않습니다.
__proto__ pollution
Exploring Prototype Pollution in JavaScript
JavaScript 객체는 키-값 쌍으로 정의되며 JavaScript Object 프로토타입에서 상속됩니다. 이는 Object 프로토타입을 변경하면 환경 내의 모든 객체에 영향을 미칠 수 있음을 의미합니다.
다른 예제를 사용하여 설명해 보겠습니다:
Object 프로토타입에 대한 접근은 다음을 통해 가능합니다:
Object 프로토타입에 속성을 추가함으로써, 모든 JavaScript 객체는 이러한 새로운 속성을 상속받게 됩니다:
prototype pollution
__proto__
사용이 제한된 시나리오에서는 함수의 프로토타입을 수정하는 것이 대안입니다:
이것은 Vehicle
생성자에서 생성된 객체에만 영향을 미치며, 이들에게 beep
, hasWheels
, honk
, 및 isElectric
속성을 부여합니다.
프로토타입 오염을 통해 JavaScript 객체에 전역적으로 영향을 미치는 두 가지 방법은 다음과 같습니다:
Object.prototype
를 직접 오염시키기:
일반적으로 사용되는 구조체의 생성자 프로토타입 오염:
이 작업 후, 모든 JavaScript 객체는 goodbye
및 greet
메서드를 실행할 수 있습니다.
다른 객체 오염시키기
클래스에서 Object.prototype으로
특정 객체를 오염시킬 수 있는 시나리오에서 Object.prototype
에 접근해야 하는 경우, 다음과 같은 코드로 검색할 수 있습니다:
Array elements pollution
JS에서 객체의 속성을 오염시킬 수 있는 것처럼, 배열에 접근하여 오염시킬 수 있다면 인덱스를 통해 접근 가능한 배열의 값도 오염시킬 수 있다는 점에 유의하세요 (값을 덮어쓸 수는 없으므로, 어떤 식으로든 사용되지만 작성되지 않은 인덱스를 오염시켜야 합니다).
Html elements pollution
JS를 통해 HTML 요소를 생성할 때 innerHTML
속성을 덮어쓸 수 있어 임의의 HTML 코드를 작성할 수 있습니다. 이 글에서 아이디어와 예시입니다.
Examples
Basic Example
프로토타입 오염은 Object.prototype
의 속성을 덮어쓸 수 있는 애플리케이션의 결함으로 인해 발생합니다. 이는 대부분의 객체가 Object.prototype
에서 속성을 파생하기 때문에 의미합니다.
가장 쉬운 예는 확인될 정의되지 않은 객체의 속성에 값을 추가하는 것입니다.
If the attribute admin
is undefined it's possible to abuse a PP and set it to True with something like:
속성이 admin
이 정의되지 않은 경우 PP를 악용하여 다음과 같이 True로 설정할 수 있습니다:
이 메커니즘은 공격자가 특정 입력을 제어할 수 있는 경우 애플리케이션의 모든 객체의 프로토타입을 수정할 수 있도록 속성을 조작하는 것과 관련이 있습니다. 이 조작은 일반적으로 __proto__
속성을 설정하는 것을 포함하며, JavaScript에서 이는 객체의 프로토타입을 직접 수정하는 것과 동의어입니다.
이 공격이 성공적으로 실행될 수 있는 조건은 특정 연구에서 설명된 바와 같이 다음과 같습니다:
재귀적 병합 수행.
경로에 따라 속성 정의.
객체 복제.
Override function
Proto Pollution to RCE
Prototype Pollution to RCE다른 페이로드:
클라이언트 측 프로토타입 오염을 통한 XSS
Client Side Prototype PollutionCVE-2019–11358: jQuery $ .extend를 통한 프로토타입 오염 공격
자세한 내용은 이 기사를 확인하세요 jQuery에서 $ .extend
함수는 깊은 복사 기능이 잘못 사용될 경우 프로토타입 오염을 초래할 수 있습니다. 이 함수는 일반적으로 객체를 복제하거나 기본 객체의 속성을 병합하는 데 사용됩니다. 그러나 잘못 구성되면 새로운 객체를 위한 속성이 대신 프로토타입에 할당될 수 있습니다. 예를 들어:
이 취약점은 CVE-2019–11358로 식별되며, 깊은 복사가 어떻게 우연히 프로토타입을 수정할 수 있는지를 보여줍니다. 이는 isAdmin
과 같은 속성이 적절한 존재 확인 없이 확인될 경우 무단 관리자 접근과 같은 잠재적인 보안 위험으로 이어질 수 있습니다.
CVE-2018–3721, CVE-2019–10744: lodash를 통한 프로토타입 오염 공격
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 주입 논의에서 확인할 수 있습니다.
Pug에서의 프로토타입 오염 예시:
예방 조치
프로토타입 오염의 위험을 줄이기 위해 아래의 전략을 사용할 수 있습니다:
객체 불변성:
Object.prototype
을Object.freeze
를 적용하여 불변으로 만들 수 있습니다.입력 검증: JSON 입력은 애플리케이션의 스키마에 대해 철저히 검증해야 합니다.
안전한 병합 함수: 재귀 병합 함수의 안전하지 않은 사용은 피해야 합니다.
프로토타입 없는 객체: 프로토타입 속성이 없는 객체는
Object.create(null)
을 사용하여 생성할 수 있습니다.Map 사용: 키-값 쌍을 저장할 때
Object
대신Map
을 사용해야 합니다.라이브러리 업데이트: 라이브러리를 정기적으로 업데이트하여 보안 패치를 통합할 수 있습니다.
린터 및 정적 분석 도구: 프로토타입 오염 취약점을 감지하고 방지하기 위해 적절한 플러그인이 포함된 ESLint와 같은 도구를 사용하세요.
코드 리뷰: 프로토타입 오염과 관련된 잠재적 위험을 식별하고 수정하기 위해 철저한 코드 리뷰를 시행하세요.
보안 교육: 개발자에게 프로토타입 오염의 위험과 안전한 코드를 작성하기 위한 모범 사례에 대해 교육하세요.
라이브러리 사용 시 주의: 서드파티 라이브러리를 사용할 때 주의하세요. 그들의 보안 상태를 평가하고, 특히 객체를 조작하는 코드에 대해 검토하세요.
런타임 보호: 프로토타입 오염 공격을 감지하고 방지할 수 있는 보안 중심의 npm 패키지를 사용하는 등 런타임 보호 메커니즘을 사용하세요.
참고 문헌
Last updated