按框架
Next.js 安全防护 — Server Actions、环境变量与依赖 CVE 的守护方法
Next.js 的事故大多发生在『服务端/客户端的边界』:环境变量泄露(把服务端专用的密钥打包到客户端)、Server Actions 缺失授权(已认证但没有所有者范围)、依赖包的已知 CVE。把密钥限定在服务端、按所有者划分范围、监控 CVE。防御视角,不含攻击步骤。
面向:正在运营 Next.js 应用的人。这里不讲攻击步骤——只讲在服务端/客户端的边界上发生的事故,以及如何堵住它们。 想看全局,请参阅 按框架的安全防护入口。
三大陷阱(都在边界上)
Next.js 的转义与路由都很出色,但下面这三点是要靠你留意边界、亲手堵住的领域。
① 环境变量泄露
误用 NEXT_PUBLIC_,或把密钥传给客户端。被打进 bundle,访问者可见。
② action 缺失授权
Server Actions / Route Handlers 里没有所有者检查。替换一个 ID,就能操作他人的数据。
③ 依赖的已知 CVE
核心/依赖的已知 CVE(含 RCE)被放任。按实际运行版本判定,快速打补丁。
如何堵住(3 步)
把密钥限定在服务端
NEXT_PUBLIC_ 前缀,绝不加在 API 密钥或连接信息上。密钥只在服务端组件 / Server Actions / Route Handlers 内部读取,别混进 props 和响应。(→ .env 文件与密钥)在每个 Server Action / Route Handler 里做授权
用机器监控依赖 CVE 并快速打补丁
常见(危险)
- 给密钥加
NEXT_PUBLIC_前缀,暴露给客户端 - 把 Server Actions 当成「登录了就允许」
- 在服务端无防护地抓取外部 URL(SSRF)
- 放任依赖的已知 CVE
正确
- 密钥只留在服务端,绝不发给客户端
- action 做按所有者划分范围的授权
- URL 抓取走SSRF 防护(阻断内网 IP、白名单)
- 依赖 CVE 机器监控+快速打补丁
本站的视角:管理『边界与依赖』,而非核心
本站跑在 Next.js 上,我们真正把守护重心放在的不是花哨的配置,而是服务端/客户端的边界与依赖的新鲜度。密钥只留在服务端,公开入口(Server Actions / Route Handlers)一律带授权,依赖在每次部署前都做一次 CVE 审计。本站自身的出身就是一起「未打补丁的 CVE 被自动利用」的事故,所以用机器监控依赖是最优先的习惯。任何抓取外部 URL 的代码都走我们自建的 SSRF 安全网关,让它无法触及内网 IP 或元数据(→ 什么是 SSRF)。
接下来读
- 入口:按框架的安全防护 · Laravel 安全
- 依赖:不在 CVE 上掉队 · 漏洞应对实务
- 术语:什么是 IDOR · 什么是 SSRF · .env 文件与密钥
FAQ
QNext.js 是安全的框架吗?
Next.js 具备安全的默认值(输出转义等),素装状态下相当稳固。但事故并非源自核心默认,而是来自你如何处理服务端/客户端的边界:本应只留在服务端的密钥流入了客户端、Server Actions 里忘了写授权、依赖包的已知 CVE 被放任不管。不能只依赖默认值——边界和依赖要靠你自己来管理。
Q环境变量该如何安全地处理?
原则是『密钥只留在服务端』。只有可以安全放到浏览器的值才加 NEXT_PUBLIC_ 前缀,API 密钥或连接信息绝不能加(NEXT_PUBLIC_ 的值会在构建时被打进客户端 bundle,访问者可见)。密钥只在服务端组件 / Server Actions / Route Handlers 内部读取,并从设计上确保它们不会混入 props 或响应。
Q使用 Server Actions 时该注意什么?
Server Actions 和 Route Handlers 是公开的服务端入口。能被调用不等于允许执行。在登录(认证)之上,要写授权,把每个操作限定到拥有该目标的用户。忘了写,别人只要替换一个 ID 就能更新或删除他人的数据(认证≠授权)。要校验输入,并且始终在 action 里做所有者检查。