
CVE-2025-55182의 프로토타입 오염 취약점에 대한 CodeQL 기반 분석, React Server Components에서의 익스플로잇 POC 및 안전하지 않은 속성 순회를 위한 정적 탐지 쿼리 포함.
빌드 및 실행:
docker compose build
docker compose run --rm --entrypoint 'npm install' node
docker compose run --rm --entrypoint 'npm run build' node
docker compose up
POC (출처: https://github.com/msanft/CVE-2025-55182):
node poc.js
unbundled로 실험:
yarn --immutable
node --conditions react-server app.js
facebook/react를 클론하고 unbundled 생성:
yarn --immutable
yarn cross-env RELEASE_CHANNEL=experimental node ./scripts/rollup/build.js react-server-dom-webpack/ --type=NODE_DEV
cp ./build/node_modules/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js \
codeql/${version}/
CodeQL 준비:
codeql database create db -l javascript -s codeql
cd queries && codeql pack install
codeql query run ./queries/PrototypeTraversal.ql -d db
Promise.resolve(userData)를 찾는 쿼리 추가
await non-native-promise를 찾는 쿼리 추가
await를 사용할 수 있음getOutlinedModel에서 패치된 사용법(hasOwnProperty.call 추가)과 createModelResolver에서 제거된 사용법(현재 fulfillReference)을 포착했습니다.
첫 번째와 두 번째가 같은 위치를 가리키는 반면, vuln.js에서 추출된 것은 그렇지 않은 이유를 모르겠습니다.
codeql/tests.js에는 다음 세 가지 변형이 있습니다:
var value = {};
for (let i = 0; i < path.length; i++) {
value = value[path[i]] // VarAccess
}
var value = {};
for (let i = 0; i < path.length; i++) {
let c = value[path[i]] // VarDecl
value = c
}
var value = {};
for (let i = 0; i < path.length; i++) {
let c
c = value[path[i]] // use VarRef
value = c
}
| filename | source | sink |
|---|
| ./19.2.0/react-server-dom-webpack-server.node.unbundled.development.js | parentObject[reference[key]] | parentObject[reference[key]] | 안전하지 않은 프로토타입 순회: 변수 'parentObject'가 루프 내에서 자신의 속성으로 업데이트됩니다. |
| ./19.2.0/react-server-dom-webpack-server.node.unbundled.development.js | parentObject[reference[key]] | parentObject[reference[key]] | 안전하지 않은 프로토타입 순회: 변수 'parentObject'가 루프 내에서 자신의 속성으로 업데이트됩니다. |
| ./19.2.0/react-server-dom-webpack-server.node.unbundled.development.js | value[path[i]] | value[path[i]] | 안전하지 않은 프로토타입 순회: 변수 'value'가 루프 내에서 자신의 속성으로 업데이트됩니다. |
| ./tests.js | value[path[i]] | c | 안전하지 않은 프로토타입 순회: 변수 'value'가 루프 내에서 자신의 속성으로 업데이트됩니다. |
| ./tests.js | value[path[i]] | c | 안전하지 않은 프로토타입 순회: 변수 'value'가 루프 내에서 자신의 속성으로 업데이트됩니다. |
| ./tests.js | value[path[i]] | value[path[i]] | 안전하지 않은 프로토타입 순회: 변수 'value'가 루프 내에서 자신의 속성으로 업데이트됩니다. |
| ./vuln.js | parentObject[reference[key]] | parentObject[reference[key]] | 안전하지 않은 프로토타입 순회: 변수 'parentObject'가 루프 내에서 자신의 속성으로 업데이트됩니다. |
| ./vuln.js | value[path[i]] | value[path[i]] | 안전하지 않은 프로토타입 순회: 변수 'value'가 루프 내에서 자신의 속성으로 업데이트됩니다. |