Reader

Next.js 出现严重安全漏洞

| 掘金本周最热 | Default

近日,Next.js 官方披露了一个严重级别的安全漏洞(CVE-2025-29927/GHSA-f82v-jwr5-mffw),该漏洞影响了大量使用 Next.js 中间件实现授权功能的应用程序。

漏洞概述

基本信息

  • 漏洞编号:CVE-2025-29927 / GHSA-f82v-jwr5-mffw
  • 漏洞类型:授权绕过(CWE-285)
  • 严重级别:严重(Critical)
  • CVSS 评分:9.1/10.0
  • 影响版本
    • 11.1.4 至 13.5.6
    • 14.0 至 14.2.24
    • 15.0 至 15.2.2
  • 修复版本:14.2.25、15.2.3

漏洞简述

此漏洞允许攻击者通过添加特定 HTTP 请求头(x-middleware-subrequest)完全绕过在 Next.js 中间件中实现的授权检查,从而获取对受保护资源的未授权访问。由于许多 Next.js 应用仅在中间件层实现授权逻辑,这使得该漏洞的影响范围极广且危害严重。

技术深度分析

Next.js 中间件机制回顾

Next.js 的中间件功能允许开发者在页面渲染前拦截请求,实现如授权检查、请求重写等功能。中间件在服务端执行,通常位于项目根目录的middleware.js_middleware.js文件中。

一个典型的授权中间件实现如下:

import { NextResponse } from 'next/server'

export function middleware(request) {
  // 获取会话或令牌
  const token = request.cookies.get('token')?.value

  // 授权检查
  if (!token || !verifyToken(token)) {
    // 未授权,重定向到登录页
    return NextResponse.redirect(new URL('/login', request.url))
  }

  // 授权通过,继续请求
  return NextResponse.next()
}

export const config = {
  matcher: ['/dashboard/:path*', '/api/protected/:path*'],
}

漏洞原理

该漏洞的根本原因在于 Next.js 中间件处理子请求的机制存在缺陷:

  1. 内部子请求标识:当中间件需要向内部路由发出请求时(例如获取数据或验证信息),Next.js 会自动添加x-middleware-subrequest头,以标识这是一个内部请求,防止中间件陷入无限循环。

  2. 来源验证缺失:漏洞出现的关键点是 Next.js 没有正确验证这个头的来源。当外部请求携带此头时,中间件错误地将其识别为内部子请求。

  3. 中间件执行逻辑:当检测到x-middleware-subrequest头时,Next.js 会跳过对该请求的中间件执行,直接将请求传递给目标路由或 API。

  4. 授权绕过实现:攻击者只需在请求中添加x-middleware-subrequest: 1头,就能使中间件的授权检查被完全跳过,直接访问受保护资源。

漏洞复现

以下是一个简单的漏洞利用脚本:

const fetch = require('node-fetch')

async function exploitAuthBypass() {
  const response = await fetch('https://target-app.com/api/protected-data', {
    method: 'GET',
    headers: {
      // 关键漏洞利用点:添加这个头即可绕过中间件授权
      'x-middleware-subrequest': '1',
    },
  })

  if (response.ok) {
    const data = await response.json()
    console.log('成功绕过授权:', data)
  }
}

exploitAuthBypass()

影响评估

受影响场景

此漏洞主要影响以下场景:

  1. 仅依赖中间件授权:应用程序只在中间件中实现授权检查,而 API 路由或页面组件本身不做额外验证。

  2. 混合授权模式:即使实施了多层授权,如果部分路由仅依赖中间件保护,这些路由仍然易受攻击。

  3. 第三方授权库:一些基于 Next.js 中间件的授权库可能同样受到影响,尤其是那些将授权逻辑封装在中间件中的库。

具体危害

  1. 敏感信息泄露:攻击者可以访问受保护的 API 端点,获取敏感数据。
  2. 业务逻辑绕过:可以绕过基于角色的访问控制,执行未授权操作。
  3. 个人隐私风险:可能导致用户个人信息被未授权访问。
  4. 账户接管:在某些情况下,可能导致账户接管或权限提升。

全面防御策略

立即修复方案

  1. 升级 Next.js 版本

    • 对于 Next.js 15.x,升级到 15.2.3 或更高版本
    • 对于 Next.js 14.x,升级到 14.2.25 或更高版本
    • 对于 Next.js 11.1.4 至 13.5.6,应考虑升级到最新的安全版本
  2. 临时缓解措施(如无法立即升级):

    • 在网关/代理层过滤或删除所有外部请求中的x-middleware-subrequest
    • Nginx 配置示例:
      # 删除所有传入的x-middleware-subrequest头
      proxy_set_header x-middleware-subrequest "";
      
    • AWS WAF 示例规则:
      {
        "Name": "block-middleware-header",
        "Priority": 1,
        "Action": { "Block": {} },
        "VisibilityConfig": {...},
        "Statement": {
          "ByteMatchStatement": {
            "SearchString": "x-middleware-subrequest",
            "FieldToMatch": { "Headers": { "MatchPattern": "All" } },
            "TextTransformations": [{ "Priority": 0, "Type": "NONE" }],
            "PositionalConstraint": "CONTAINS"
          }
        }
      }
      

安全最佳实践

  1. 深度防御策略

    • 在 API 路由和中间件中都实现授权检查

    • 示例 API 路由实现:

      import { getServerSession } from 'next-auth/next'
      
      export default async function handler(req, res) {
        // 即使有中间件保护,也在API路由中重复授权检查
        const session = await getServerSession(req, res)
        if (!session) {
          return res.status(401).json({ error: '未授权访问' })
        }
      
        // 处理授权请求...
        res.status(200).json({ data: '敏感数据' })
      }
      
  2. 不依赖单层保护

    • 将授权逻辑从中间件移至 API 路由或页面组件
    • 使用 Next.js 的getServerSidePropsgetStaticProps进行页面级别的授权检查
  3. 使用更安全的授权模式

    • 考虑使用 JWT 或其他带签名的令牌机制
    • 实现细粒度的权限检查,不仅验证身份,还验证操作权限
  4. 使用 next-auth 的建议

    • 如果使用 next-auth,不要仅依赖中间件,同时使用getServerSession在每个路由中验证会话
    • 确保正确配置 next-auth 的回调和事件处理函数
  5. 请求验证增强

    • 对于关键 API,考虑实现请求签名机制
    • 使用 CSRF 令牌防止跨站请求伪造

检测与审计

漏洞检测方法

  1. 主动测试

    • 使用未认证的客户端向受保护 API 发送带有x-middleware-subrequest头的请求
    • 如果成功访问,则表明应用存在漏洞
  2. 日志分析

    • 检查访问日志中是否存在包含x-middleware-subrequest头的请求
    • 关注这些请求的响应状态码和相关会话信息
  3. 代码审计

    • 审查中间件实现,确认授权逻辑是否仅存在于中间件
    • 检查 API 路由是否有独立的授权验证

总结与思考

这个 Next.js 中间件授权绕过漏洞再次提醒我们,在构建 Web 应用安全架构时,不应该依赖单一防御层。虽然中间件提供了便捷的集中式授权机制,但它不应成为唯一的安全屏障。

安全是一个持续的过程,需要在开发、测试和运维的各个环节都给予足够重视。针对此类漏洞,我们不仅需要进行技术修复,更应反思整体安全架构设计,实施更全面的安全策略。

作为开发者,我们应当:

  1. 保持对安全最佳实践的学习和更新
  2. 采用多层次安全防御策略
  3. 定期进行安全审计和测试
  4. 及时更新框架和依赖到安全版本

通过这些措施,我们可以更好地保护我们的应用和用户数据安全。

参考资料

  1. GitHub 安全公告: GHSA-f82v-jwr5-mffw
  2. Next.js 官方文档: 中间件
  3. Next.js GitHub 仓库: 修复提交