文章总结: 本文系统研究Next.js攻击面,指出框架收敛多能力导致边界变薄。关键发现包括__NEXT_DATA__数据泄露、资源代理SSRF风险、ServerActions权限缺陷、缓存边界错误及SourceMap暴露敏感信息。文章提出优先检查数据传递、资源代理和缓存行为的测试路径,强调先看清行为再测试的原则,为安全研究者提供了系统化的Next.js安全审计方法论。 综合评分: 87 文章分类: 渗透测试,WEB安全,红队,安全建设,实战经验
真实项目里为什么容易埋坑
开发团队往往为了方便,会希望:
- 支持更多图片来源
- 支持第三方 CDN
- 支持更多资源站点
- 支持自动重定向和兼容
一旦这些能力越开越宽,边界就容易松。所以你在测 Next.js 时,只要看到框架在“替用户取资源”,脑子里就要亮灯。不是说一定有问题,而是这种设计天然更值得安全研究员多看两眼。
你重点看什么
- 来源限制是不是过宽
- 是否允许跨域资源来源太多
- 是否存在可控跳转链
- 是否存在可被服务端拉取的远程地址
- 是否还有文件类型、SVG、内容处理等附加风险
这类点一旦出问题,通常不只是“拿一张图片”这么简单,它往往会往更高价值的方向扩展。
七、不要把 Server Actions 只当成新语法
很多人第一次看到 Server Actions,会把它当成一个开发体验优化。其实从安全视角看,它更像是:**把一部分原来需要接口承载的服务端操作,换了一种形式暴露出来。**这就意味着一个关键点:原来接口该有的安全问题,它大概率也还是会有,只是表现形式不一样。
为什么它值得重点研究
因为它让“前端触发服务端动作”这件事变得更自然了。自然的另一面,就是开发者更容易忽略边界,比如:
- 这个动作到底该谁触发
- 来源校验做没做
- 权限校验是不是写在服务端真正入口上
- 某些情况下会不会被错误转发或错误重定向
一个简单例子
开发者原本可能会写一个 /api/update-profile 接口。后来换成 Server Actions 之后,前端看起来只是“点一下按钮”,后面却还是发生了真实的服务端状态变更。这时候研究员该问的不是“这语法新不新”,而是:
- 谁能触发它
- 触发条件是什么
- 服务端有没有独立做权限判断
- 请求来源和宿主信息有没有被错误信任
如果再说得更短一点,Server Actions 值得看的原因,往往不是因为它“新”,而是因为它让很多原本看起来像接口的事情,不再以传统接口的样子出现了。入口样子变了,边界问题通常并不会一起消失。
实战里为什么要盯紧它
因为这种新能力经常会出现两个问题:
- 开发者习惯还没完全跟上
- 生态周边的最佳实践还没完全沉淀
所以你会看到一些项目里,用法是新的,边界却还是旧的,结果就会出事。如果目标是较老版本、或者工程质量一般的项目,Server Actions 往往值得认真翻。
八、缓存问题经常比表面上更有研究价值
很多人一提缓存,第一反应是性能,不是漏洞。但在现代 Web 里,**缓存配错了,经常能直接变成安全问题。**而 Next.js 又很依赖缓存思路,所以这一块尤其不能放过。
为什么缓存会出问题
因为缓存机制本质上做的是一件事:
这次请求的结果,下次能不能直接拿来复用。
问题就出在“复用边界”上。如果系统没分清:
- 哪些内容是公共的
- 哪些内容是用户私有的
- 哪些 header 会影响结果
- 哪些页面不该被共享
那就有可能出现:
- 本该只给一个用户的内容,被缓存给别人
- 本该受上下文影响的页面,被按公共资源缓存
- 某些可控输入进入缓存结果,影响后续访问者
一个最容易理解的例子
假设 /dashboard 页面本来应该是登录后用户自己的页面。但如果缓存层把它当成公共页面处理了,那么理论上就可能出现:
- 用户 A 访问后生成了一份缓存
- 用户 B 再访问时拿到的是这份缓存结果
你真正要测试的,不是“缓存有没有存在”,而是:**缓存有没有把不该共享的东西共享出去。**同样地,如果一个站点的订单页、个人中心页、后台概览页在响应头上都表现得像公共资源,那你就不该再把它只当成性能问题,而应该开始怀疑:这里是不是把用户态页面缓存成了可复用页面。
为什么 Next.js 更值得看缓存
因为它本身就鼓励很多性能优化思路:
- 静态生成
- 增量更新
- 边缘缓存
- 页面复用
- 数据缓存
这些本身都没错,但只要“个性化内容”和“公共缓存”边界没划清,问题就会开始冒出来。
你重点看什么
- 个性化页面是否出现公共缓存特征
- 登录态内容是否被错误复用
- 某些 header 是否能影响缓存内容
- 页面是否存在不该共享的用户数据
缓存问题的魅力在于:**它经常不是“一个点打穿”,而是“一个配置理解错了,整个行为都偏了”。**这种问题在赏金里很讨喜,因为如果你能证明影响范围,价值通常不低。
九、Source Map 依然是一个很好用的观察窗口
很多研究员会下意识觉得 Source Map 是“老问题”,好像不够高级。但我一直觉得,这类问题的价值不在于它是不是新,而在于:它能不能把原本看不清的前端逻辑,重新摊开给你看。
它的意义是什么
前端打包之后,代码经常已经压缩、混淆、拆块了。你直接读那些产物,很费劲,也很容易漏东西。一旦 Source Map 泄露,你看到的就不再是一团打包产物,而更接近开发者原本写出来的结构。这意味着什么?
- 更容易看清真实路由和调用关系
- 更容易发现隐藏接口
- 更容易发现调试逻辑
- 更容易看到命名语义
- 更容易顺着代码看权限和功能边界
一个很现实的价值
在没有 Source Map 的情况下,你可能只能看见一坨压缩后的变量名。有了 Source Map 之后,你更容易直接看到类似这样的语义:
adminApidebugModeinternalBaseUrluseServerAction
这会极大缩短你理解业务结构的时间。
为什么它在 Next.js 里有价值
因为 Next.js 项目通常前端逻辑不少,打包以后可读性下降很明显。一旦恢复结构,很多本来“只能猜”的东西,会直接变成“肉眼可读”。
一个很常见的变化是:原本你只能模糊地猜测“这里可能有个内部接口”,有了 Source Map 之后,这种猜测会迅速变成更具体的观察——接口名是什么、调用发生在哪里、它和哪个页面状态绑定在一起。对研究员来说,这种差别往往就已经足够大了。
你该怎么用这个线索
不要把它只当成“信息泄露”本身。更好的思路是:**把它当成后续所有测试的放大镜。**它不是终点,而是让你后面更快找到高价值点的工具。
十、内容渲染链经常决定问题会不会浮出来
如果一个 Next.js 项目里存在这些功能:
- 博客发布
- 评论系统
- 富文本编辑
- Markdown 渲染
- 可视化内容编辑
- CMS 内容同步
那你几乎就应该立刻想到一件事:内容是怎么进 DOM 的。
为什么这里容易出问题
因为 React 默认是会帮你做一层转义的,这本来是好事。但很多业务为了显示格式化内容,会主动绕开这层保护,比如:
- 把 Markdown 转成 HTML 再渲染
- 允许后台内容带样式或标签
- 做富文本预览
- 引入第三方内容编辑器
一旦这条链里有一环做得不稳,XSS 风险就会出现。
一个简单例子
假设开发者把用户输入的 Markdown 转成 HTML 后,直接塞进页面。从功能角度看,这是“让内容显示得更漂亮”。从安全角度看,这就是在问:
- HTML 有没有被净化
- 哪些标签和属性被保留了
- 最终是以什么方式进入 DOM 的
这类问题不一定靠爆 payload 才能发现,很多时候看清渲染链本身,就已经很接近答案了。
你不要只盯着“输入框”
这类问题不一定只出在用户手填内容上,也可能出在:
- 后台导入的数据
- 第三方 CMS 同步内容
- 营销活动模板
- 帮助中心或公告系统
也就是说,越是“看起来像内容系统”的页面,越值得多看渲染链。
十一、工程侧线索有时比页面本身更诚实
Next.js 项目往往和 Node.js 生态深度绑定,所以它不仅有运行时攻击面,也会有很强的工程侧线索。比如:
- 包管理文件
- 配置文件
- 环境变量痕迹
- 私有包命名
- 构建与部署信息
为什么这部分重要
因为很多时候,你不是直接从“漏洞利用”里拿结果,而是从“工程侧泄露”里拿线索。这些线索可能不会立刻变成一个洞,但它们经常能告诉你:
- 项目依赖了什么
- 开发团队怎么组织工程
- 有没有私有包和内部体系
- 有没有暴露出进一步分析的入口
一个常见思路
如果你拿到了依赖、配置、构建痕迹,这些信息本身可能不算最终结果。但它们会帮你更快判断:
- 哪些组件值得深看
- 有没有版本相关的历史问题
- 有没有内部包、内部路径、内部命名体系
也就是说,它们不一定是漏洞本身,但常常是高价值漏洞的路标。
这类点的价值在哪
在高质量目标里,工程信息往往比表面页面更诚实。页面会伪装,构建产物和配置痕迹通常不会。所以你在看 Next.js 项目时,不要只盯着页面和接口,也要保留一个工程视角:这套东西是怎么被构建、被组织、被部署出来的。
再举一个很短的例子:假设你没有直接找到洞,但你从构建痕迹里看到了 internal-admin-sdk、staffOnlyApi、debugToolbar 这类命名。它们本身可能还不构成结果,但对研究员来说,这已经足够说明两件事:
- 这个项目大概率有内部能力和外部能力的分层
- 这些分层未必在每个入口都做对了隔离
很多时候,真正有价值的发现,不是从首页一路打进去,而是先从这些工程侧线索里闻到“哪里可能有内部边界”。
十二、如果要实战起手,可以按这个顺序看
如果你已经确认目标是 Next.js,但还不想一上来就把时间花在很散的枚举和试探上,一个更稳的起手方式通常是:先确认框架痕迹,再看页面怎么拿数据,再看那些最容易暴露边界问题的位置。
第一步:先确认它是不是 Next.js
很多时候这个并不难。
你可以从下面这些痕迹判断:
- 页面源码里有没有
__NEXT_DATA__ - 静态资源路径里有没有
_next/static - 页面和资源结构是否符合 Next.js 常见特征
先确认技术栈,后面很多动作才有针对性。
第二步:先看源码,不要急着打
重点看:
__NEXT_DATA__- 页面里是否带了过多数据
- 是否能看出服务端渲染痕迹
- 是否能看出运行时配置
第三步:看 JS 和前端调用关系
重点不是“把 JS 全下载一遍就结束”,而是弄清楚:
- 页面会调哪些接口
- 哪些接口像内部管理接口
- 哪些功能只在前端做了限制
- 哪些内容渲染链看起来不太稳
第四步:看特殊特性
也就是 Next.js 特别值得看的那些东西:
- 图片优化
- Server Actions
- 中间件
- 缓存行为
第五步:最后再做更细的深挖
比如:
- 缓存问题验证
- 权限与身份边界验证
- 多角色、多账号对照测试
- 老版本特性的兼容问题
这个顺序的核心其实很简单:
先看清行为,再决定怎么测。
这样做不一定最炫,但在真实目标里通常更省时间。
十三、如果刚开始研究,可以先把这三个点练熟
如果你刚开始研究 Next.js,我建议你先别想一步到位全掌握。先把下面三个点练熟,性价比最高。
1. __NEXT_DATA__ 数据审计
因为这是最容易上手,也最能帮你建立 Next.js 安全感觉的点。你只要开始认真看这类数据结构,很快就会对“哪些东西本来不该被前端看到”形成直觉。
2. 内容渲染链
因为这个最容易帮助你把 React、前端渲染和 XSS 风险串起来。你会慢慢明白:不是 React 天生安全,而是 React 默认帮你挡了一层;一旦业务主动绕开,问题就回来了。
3. 缓存和页面复用逻辑
因为这个最能拉开你和普通测试者的差距。很多人只会盯着输入输出,而不会看缓存边界。但真正高价值的问题,往往就藏在“这个页面为什么会被复用给另一个人”这种地方。
十四、一个常见误区:不要把 Next.js 只当成“换皮 React”
这是一个很常见的误区。如果你只是把 Next.js 当成 React 的套壳,那你会天然忽略掉很多服务器侧和框架层问题。更准确的理解应该是:**Next.js 是一个把前端体验、服务端能力、缓存机制和工程能力揉到一起的框架。**这意味着你测它的时候,也要用一个更立体的脑子:
- 既看前端
- 也看后端
- 既看页面
- 也看框架行为
- 既看接口
- 也看缓存与渲染路径
一旦你这么看,很多原来你以为“只是个前端项目”的目标,会突然变得很有意思。
十五、最后总结:真正值得研究的,通常不是功能本身,而是边界
如果只用一句话概括 Next.js 的安全研究重点,我更倾向于这样说:
不要急着把它拆成一串漏洞名词,先去看边界是怎么被处理的。
这个框架里反复出现问题的地方,往往都和边界有关:
- 服务端和前端的边界
- 公共数据和私有数据的边界
- 本地资源和远程资源的边界
- 用户请求和服务端代请求的边界
- 动态页面和缓存页面的边界
当这些边界被处理得足够清晰时,很多问题不会出现;但当这些边界被藏进抽象层、默认配置或者“图方便”的工程写法里时,问题就会开始以一种不太显眼的方式浮出来。
这也是为什么 Next.js 值得研究。
它并不是一个“天然更危险”的框架。更准确地说,它是一个很容易把复杂能力收敛到一起的框架,而只要能力收敛得足够多,研究员就有必要重新检查:哪些事情被简化了,哪些边界也在这个过程中一起被简化了。
所以如果你后面还会继续看 Next.js,一个很有用的习惯通常不是先问“今天我要找什么漏洞”,而是先问:
这里原本应该清晰分开的东西,现在是不是被框架替我揉到一起了?
很多真正有研究价值的发现,往往就是从这个问题开始的。
如果这篇文章能帮你建立起这个观察角度,那它的目的就已经达到了。
附:一个更适合实战的 Next.js 快速检查清单
基础识别
- 这个目标是不是 Next.js
- 页面里有没有
__NEXT_DATA__ - 静态资源里有没有
_next/static - 是否能看出 SSR、静态生成或其他渲染痕迹
数据暴露
- 页面源码里有没有多余数据
- 用户对象有没有带过多字段
- 有没有内部地址、调试字段、配置项
- 有没有明显不该暴露给前端的运行信息
前端与渲染链
- 富文本/Markdown 是怎么渲染的
- 有没有主动绕开默认转义
- 有没有内容直接进 DOM 的链路
- 有没有高风险编辑器或模板场景
服务端代请求能力
- 框架是否替用户拉远程资源
- 图片、文件、远程内容处理边界是否过宽
- 是否存在值得深挖的来源校验问题
新特性与权限边界
- 是否使用 Server Actions
- 状态变更动作的边界是否明确
- 是否只做了前端限制,没有做服务端兜底
缓存行为
- 个性化页面是否存在公共缓存痕迹
- 缓存键是否合理
- 是否存在页面复用给错误用户的可能
- 是否有可控输入影响缓存结果
工程侧线索
- 是否有 Source Map 暴露
- 是否能看出依赖和构建结构
- 是否存在配置痕迹、包管理线索、环境信息线索
参考方向: Next.js 官方文档、真实项目源码、框架版本更新日志、公开安全研究文章、缓存与渲染相关案例分析。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Zacarx随笔 Zacarx Zacarx《从 NEXT_DATA 到 Server Actions:Next.js 攻击面研究笔记》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论