Strix Next.js 安全测试技能实战:面向 App Router、Server Actions、RSC 与 Edge Runtime 的渗透测试指南
在 Strix(开源 AI 渗透测试工具)中,框架类技能(framework skill)是专门面向具体 Web 技术栈的“攻防剧本”,本文所讲解的 nextjs 技能即属此类,存放于 strix/skills/frameworks/nextjs.md,文档的 frontmatter 将该技能定位为 “Security testing playbook for Next.js covering App Router, Server Actions, RSC, and Edge runtime vulnerabilities”。阅读完本文,你将掌握:如何在 Next.js 应用中系统枚举路由与 Server Action、如何验证 Middleware 绕过与跨运行时(Edge/Node)的授权漂移、如何定位 RSC 缓存边界与 __NEXT_DATA__ 数据过度暴露问题,以及如何把这一整套方法论交给 Strix 的子 Agent 自动执行并用可复现证据收敛漏洞报告。
技能定位:Strix 如何消费这份 Next.js 攻防剧本
Strix 的 Skills 机制把专家级安全测试知识组织成带 YAML frontmatter(name / description)的 Markdown 知识包,按类别存放,框架类位于 strix/skills/frameworks/ 目录。与 nextjs 并列的还有 fastapi 技能,两者结构一致——均以 “Attack Surface → High-Value Targets → Reconnaissance → Key Vulnerabilities → Bypass Techniques → Testing Methodology → Validation Requirements” 的节奏铺陈(参见 skills 说明文档 与 docs/advanced/skills.mdx 中的分类表)。
技能内容通过两条路径进入 Agent 上下文:
- 静态注入:Agent 创建时通过
create_agent(..., skills=[...])或底层build_strix_agent(skills=...)(实现见 strix/agents/factory.py)指定最多 5 个技能;渲染系统提示词时,strix/agents/prompt.py 会调用load_skills()解析 frontmatter、剔除元数据后把正文注入模板,并为每个技能注册get_skill全局函数供模板按名取用。每个 Agent 还会无条件叠加scan_modes/<mode>、tooling/agent_browser、tooling/python以及analysis/severity_calibration等基础技能(见 strix/agents/prompt.py 的_resolve_skills排序逻辑)。 - 按需拉取:Agent 在运行中若发现目标栈未预载技能,可调用
load_skill工具,将指定技能的 Markdown 正文以内联工具结果的形式加入会话(见 strix/tools/load_skill/tool.py),技能名与文件名一一对应,例如["nextjs"]。
frontmatter 的解析与名称校验(重名检测、数量上限、category/name 限定写法、自定义技能目录 register_skill_dir)由 strix/skills/init.py 完成。因此,把 nextjs 技能挂到“前端框架安全专员”子 Agent 上是开箱即用的:见 create_agent 工具定义(strix/tools/agents_graph/tools.py)中的原则 “Most agents need at least one skill to be useful”。在模块级 Agent 图的 spawn_child_agent 工厂中,技能同样被逐层透传(strix/core/execution.py)。
下面按该技能的原生骨架展开其全部内容。
攻击面全景:先把 Next.js 应用的边界拆解清楚
Next.js 应用是一个多运行时、多路由体系、多层缓存的复合体,技能文档将攻击面划分为五个维度,这也是后续侦察与漏洞验证的索引。
Routers(路由体系)
- App Router(
app/目录)与 Pages Router(pages/目录)经常共存于同一项目,二者授权逻辑可能不一致; - Route Handlers(
app/api/**)与 API routes(pages/api/**)是两套独立实现; - Middleware:项目根目录的
middleware.ts,是集中式访问控制的常见落点,也是绕过测试的首要目标。
Runtimes(运行时)
- Node.js:完整 API 访问能力;
- Edge:运行在 V8 isolate,API 受限,依赖 Node-only 模块的防护在 Edge 上可能被静默跳过。
Rendering & Caching(渲染与缓存)
- SSR、SSG、ISR、on-demand revalidation 四类取数策略;
- RSC(React Server Components)及其内置 fetch cache;
- Draft/preview mode(草稿/预览模式)。
Data Paths(数据通道)
- Server Components 与 Client Components;
- Server Actions:以携带
Next-Action头的流式 POST 传输,是独立的攻击面; - 传统数据获取函数
getServerSideProps、getStaticProps。
Integrations(集成组件)
- NextAuth.js:callbacks、CSRF、
callbackUrl处理; next/image图片优化与远程 loader 配置。
技能文档强调的核心关注点是三类系统性风险:跨运行时(Edge/Node)的授权漂移(authorization drift)、缓存边界(caching boundaries)、以及 Server Actions / Middleware 绕过。
高价值目标清单
并非所有路由都值得同等投入,nextjs 技能给出的优先级清单:
- Middleware 保护的路由(鉴权、地理围栏、A/B 实验分流)——绕过它们即可越权;
- 管理后台/员工路径、草稿与预览内容、on-demand revalidate 端点(
revalidatePath/revalidateTag的触发入口); - RSC payload(flight data)与流式响应——可能携带序列化的敏感字段;
- 图片优化器与自定义 loader,以及
remotePatterns/domains白名单配置; - NextAuth callbacks(
/api/auth/callback/*)与各 sign-in provider——状态/nonce/PKCE 缺失的高发区; - 仅 Edge 具备的特性(机器人防护、IP 门禁)及其 Node 端等价实现——两套实现往往只在一边生效。
侦察(Reconnaissance):建立完整的路由与动作清单
侦察的目标不是扫到一个 200,而是拿到“部署状态下真实可达”的完整路由矩阵。技能文档给出五类手段,均可在 Agent 的 shell/浏览器能力下自动化执行。
路由发现(Route Discovery)
浏览器控制台是最直接的入口,三类内置数据分别暴露路由表、服务端取数与公开环境变量:
// Browser console - list all routes
console.log(__BUILD_MANIFEST.sortedPages.join('\n'))
// Inspect server-fetched data
JSON.parse(document.getElementById('__NEXT_DATA__').textContent).props.pageProps
// List public environment variables
Object.keys(process.env).filter(k => k.startsWith('NEXT_PUBLIC_'))
注意区分形态:Pages Router 会把路由表写入 __BUILD_MANIFEST,而服务端下发的数据(App Router 页面同样适用)会序列化在 __NEXT_DATA__ 脚本节点中;凡以 NEXT_PUBLIC_ 前缀开头的环境变量会被打包进客户端产物,属于默认公开面。
构建产物(Build Artifacts)
路由→分块文件名的映射是可预测的,直接抓取即可还原目录结构:
GET /_next/static/<buildId>/_buildManifest.js
GET /_next/static/<buildId>/_ssgManifest.js
GET /_next/static/chunks/pages/
GET /_next/static/chunks/app/
分块文件名与路由一一对应(例如 admin.js 指向 /admin),配合 app/ 与 pages/ 两套 chunk 目录,可以快速建立“隐藏路由”清单。
Source Maps
检查 /_next/static/ 下是否暴露了 .map 文件。泄露的 source map 会直接揭示:完整路由结构、Server Action 的 action ID、以及内部函数名——它是后续发现隐藏动作的“藏宝图”。
客户端产物挖掘(Client Bundle Mining)
在 main-*.js 中检索路由与动作线索:pathname:、href:、__next_route__、serverActions、各类 API 端点字符串;再用 API_KEY、SECRET、TOKEN、PASSWORD 等模式 grep 产物,查找被意外打进客户端包的密钥。许多团队“只在 UI 层隐藏路由/管理员开关”,因此产物里常能找到后端路径与 preview/admin 标志位。
Server Action 发现
在浏览器 Network 面板中筛选携带 Next-Action 头的 POST 请求:action ID 既出现在请求头中,也可能藏在响应流与 hydration 数据里。拿到 action ID 后即可在 UI 流程之外直接构造请求调用(见下文 Server Actions 漏洞)。
附加泄漏面
/sitemap.xml、/robots.txt、/sitemap-*.xml常包含无意的 admin/internal/preview 路径;- 客户端产物与环境变量中暴露的秘密路径、preview/admin 标志。
关键漏洞类别与测试要点
侦察完成后进入验证阶段。nextjs 技能把验证重点收敛为九类高频漏洞,以下逐类展开其测试意图。
Middleware 绕过
Middleware 是 Next.js 集中式访问控制的默认位置,其与路由处理器之间的**解析差异(normalization differential)**是主要突破口。
已知技术
- 构造
x-middleware-subrequest头(CVE 类绕过,可能被用于内部重放请求从而跳过外部访问检查); x-nextjs-data探测:观察是否命中数据请求路径而绕过页面级中间件;- 留意
307+x-middleware-rewrite/x-nextjs-redirect头——中间件发生了重写/重定向,若目标端点跳过中间件则检查失效。
路径归一化差异
/api/users
/api/users/
/api//users
/api/./users
Middleware 与 Route Handler 对路径的归一化可能不同。测试要点:双重斜杠、尾部斜杠、点段(./..)都要逐一比对响应差异,寻找中间件判定“放行”而处理器实际“执行”的归一化分叉。
参数污染
?id=1&id=2
?filter[]=a&filter[]=b
当中间件检查第一个值而处理器使用最后一个值(或把重复参数解析为数组)时,即可用两个不同的值同时骗过检查和作用于业务逻辑。
Server Actions
Server Actions 通过流式 POST + Next-Action 头传输,是 App Router 独有的攻击面,验证重点是“脱离 UI 流程的越权调用”:
- 使用备选 content-type 在 UI 之外直接调用动作(JSON/form/multipart 转换常能绕过客户端侧约束);
- 检查授权是否由客户端状态推定(例如把
isAdmin之类的布尔值放进动作 payload),而非在服务端重新强制; - 动作 payload 中的对象引用是 IDOR 的高发点(直接换用他人的对象 ID);
- 借助 source maps 把隐藏 action ID 映射出来,发现 UI 不可达的管理动作。
RSC 与缓存(Caching)
Next.js 的组件级/路由级缓存让“缓存边界错误”成为数据泄露的温床。
缓存边界失败(Cache Boundary Failures)
- 用户绑定数据未使用身份相关键缓存(缓存键对 ETag / Set-Cookie 不敏感),导致个性化内容被共享缓存/CDN 提供给其他用户;
- 对含敏感数据的 fetch 缺少
no-store。
Flight 数据泄露(Flight Data Leakage)
检查流式 RSC payload:序列化到 props 中的字段可能远超页面实际渲染所需,敏感字段会随之流向客户端。
ISR 问题
- stale-while-revalidate 期间响应了包含用户特定/租户特定数据的旧缓存;
- on-demand revalidation 端点 URL 使用了弱 secret(可枚举/可猜测);
revalidatePath/revalidateTag由 Referer 泄露的 token 或未经校验的 Host 触发(构造带 Referer 的请求泄露签名 token);- 通过 header-smuggling 或方法变体(HEAD/OPTIONS/大小写变体)触发重验证。
认证(NextAuth 与会话边界)
NextAuth 陷阱
- 各 provider 缺失/放宽
state、nonce、PKCE:引发登录 CSRF、token mix-up; callbackUrl存在开放重定向,或 allowed hosts 作用域过宽;- JWT 的
audience/issuer未跨路由强制校验; - 跨服务 token 复用(同一 token 被多个后端互信);
- 通过强制 callback(诱使受害者访问恶意 callback 完成流程)实现会话劫持。
会话边界
- App Router 与 Pages Router 的鉴权强制不一致;
- API routes 与 Route Handlers 的授权规则漂移——同一资源在两个路由体系下权限不同。
数据过度暴露(Data Exposure)
__NEXT_DATA__ 的 Over-fetching 是 Next.js 最具代表性的信息泄露:服务端取回的数据被传入客户端但从未渲染。典型形态:
- 只需要用户名却把完整 user 对象下传;
- props 携带内部 ID、token、admin-only 字段;
- ORM
select-all模式把整条记录序列化进页面; - API 响应未经净化直接透传(元数据、游标、调试信息)。
环境相关暴露
- staging/dev 环境比生产暴露更多字段;
- 不同环境的序列化逻辑不一致,导致“生产也泄露”的回归。
Props 检查
// Check for sensitive data in page props
JSON.parse(document.getElementById('__NEXT_DATA__').textContent).props
重点排查 _metadata、_internal、__typename(GraphQL 类型名)以及嵌套的敏感对象。
图片优化器 SSRF(Image Optimizer SSRF)
next/image 的服务端优化器天然是一个“可控 URL 请求器”,验证两方面:
远程白名单
next.config.js中过宽的images.domains/remotePatterns;- 测试对象:内网主机、IPv4/IPv6 变体(
127.0.0.1、[::1]、十六进制/八进制编码)、DNS rebinding。
自定义 Loaders
- 通过重定向链进行协议走私(redirect 到
file:///内网等); - URL 归一化差异引发的缓存投毒——你请求的变体被缓存后会影响其他用户的响应。
运行时分歧(Runtime Divergence)
Edge vs Node
- 依赖 Node-only 模块(
fs、crypto、child_process等)的防御在 Edge 上被静默跳过; - 对头的信任策略不同(例如
x-forwarded-*的处理差异),IP 门禁、来源校验结果因此不同; - 同一条路由在不同运行时下行为不一致——这是授权漂移的重要来源。测试时应对每条关键路由在 Edge 与 Node 两种部署形态下分别发请求对比。
客户端侧(XSS 与 Hydration)
XSS 向量
dangerouslySetInnerHTML直插不可信内容;- Markdown 渲染器(XSS 高发组件);
- 用户可控的
href/src属性(javascript:、data:协议注入); - 校验 CSP / Trusted Types 对 SSR、CSR 与 hydration 阶段的覆盖是否一致。
Hydration Mismatches
服务端与客户端渲染结果不一致会留下可被 gadget 利用的差异,这类 XSS 往往绕过了只针对纯 SSR 或纯 CSR 的过滤器。
草稿/预览模式(Draft/Preview Mode)
- 使能预览的 secret URL / cookie 是否存在且可枚举;
- preview secret 是否被打进客户端产物/环境变量(
NEXT_PUBLIC_*); - 能否通过子域或开放重定向设置 preview cookie(跨域注入会话)。
通用绕过技术(Bypass Techniques)
技能文档将跨类别的绕过手段提炼为四类,均可自动化成“矩阵请求”:
- Content-type 切换:
application/json↔multipart/form-data↔application/x-www-form-urlencoded——不同 content-type 命中不同解析器与校验分支; - 方法覆盖:
_method参数、X-HTTP-Method-Override头、对只应接受写操作(POST/PUT/DELETE)的端点改用 GET(缓存/CDN/日志可能放行); - 大小写与参数别名:大小写变体、参数别名、查询参数重复——制造中间件与处理器之间的解析差(中间件取首个值,处理器取末值或数组);
- 缓存键混淆:CDN/代理缺少对鉴权 cookie/头(Authorization、Cookie、租户头)的
Vary声明,导致鉴权用户的响应被缓存并分发给匿名用户。
六步测试方法论
nextjs 技能给出了可执行的顶层流程,前两步建立面,后四步做纵深验证:
- Enumerate(枚举)——用
__BUILD_MANIFEST、source maps、构建产物、sitemap/robots 映射全部路由; - Runtime matrix(运行时矩阵)——在 Edge 与 Node 运行时下逐条测试路由;
- Role matrix(角色矩阵)——以匿名/普通用户/管理员三种身份,横跨 SSR、API routes、Route Handlers、Server Actions 四类通道测试同一操作;
- Cache probing(缓存探测)——验证缓存是否尊重身份(剥离 cookie、篡改
Vary头、观察 ETag 是否碰撞); - Middleware validation(中间件验证)——测试路径变体与头操纵,寻找绕过;
- Cross-router(跨路由体系比对)——对比 App Router 与 Pages Router 等价路径的授权差异。
验证要求:把发现收敛成可复核证据
该技能对“如何证明漏洞”的要求极为严格,这直接服务于 Strix 的漏洞报告工具(create_vulnerability_report 等,见 strix/tools/reporting/tool.py)与反证/严重度校准纪律(Agent 无条件加载的 counterevidence 技能 与 severity_calibration 技能)。逐条满足以下证据门槛:
- 并行请求对比:证明跨用户/跨租户访问,需要“User A 的请求 vs User B 的请求”并排呈现;
- 缓存边界失败证据:给出响应差异(同一 URL 不同身份收到彼此数据)或 ETag 碰撞;
- Server Action 越权:在 UI 之外以不足授权调用动作成功;
- Middleware 绕过:用显式构造的头部展示受保护内容可达;
- 运行时一致性:Edge 与 Node 强制不一致的对比请求;
- 路由确实已部署:发现的“隐藏路由”必须以 200/403 的部署态响应为准,仅存在于构建产物(404)不算数;
- 泄露凭据:用最小化的只读请求验证,先过滤占位符/蜜罐值,避免触发告警或误报;
__NEXT_DATA__暴露:验证跨用户性质(User A 的 props 不应包含 User B 的 PII),并确认暴露字段确实未出现在 DOM 渲染中(否则属正常 SSR 输出而非泄露);- 路径归一化绕过:以 403 vs 200 的差异响应为准,重定向不算绕过证据。
把该技能接入 Strix 扫描的实战姿势
综合以上内容,可以在 Strix 中按三种姿势编排 Next.js 专项扫描:
- 作为常驻专家:目标明确为 Next.js 时,用 create_agent 工具 孵化 “Next.js Auth Specialist”“Middleware Bypass Validator”“ISR/Cache Tester” 等子 Agent,并为其传入
skills=["nextjs"](必要时叠加 fastapi 技能 覆盖目标站点里可能存在的 API 服务);Agent 的系统提示词会因技能注入而自动具备本剧本的枚举顺序与验证纪律,参见 strix/agents/prompt.py 的注入实现。 - 按需拉取:若 Agent 中途发现目标栈是 Next.js 而自身未预载,直接调用
load_skill工具并传入["nextjs"](strix/tools/load_skill/tool.py),知识立即以内联参考形式可用,无需重建 Agent。 - 配合源码级分析:在拿到源码的白盒/灰盒场景下,可将
nextjs技能与 source_aware_whitebox、source_aware_sast 等协调/分析技能叠加——前端先按本剧本做黑盒验证,再结合源码精确核对 Middleware 顺序、Route Handler 授权与next.config.js的images白名单,最终由 root agent 依据 root_agent 编排技能 汇总跨 Agent 结论,按 severity rubric 定级并生成附带完整证据链的漏洞报告。
无论采用哪种姿势,都建议把本技能“验证要求”一节的证据标准作为报告的最低门槛——在 Strix 的取证与反证纪律下,只有满足“并排请求 + 差异响应 + 排除重定向/404 干扰”的发现,才具备进入报告的资格。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00