
Geth 源码系列:存储设计及实现
在区块链的世界中,状态存储是每一个节点的「记忆核心」 — — 它记录着亿万账户的余额、合约的代码、交易的痕迹,甚至决定着一笔交易能否被正确执行。作为以太坊生态的基石,Geth 客户端如何以精密的架构设计承载海量状态数据?其存储系统如何在性能、安全与可扩展性之间找到平衡? 这篇文章是 Geth 源码系列的第二篇,通过这个系列,我们将搭建一个研究 Geth 实现的框架,开发者可以根据这个框架深入自己感兴趣的部分研究。这个系列共有六篇文章,在这第二篇文章中,将系统讲解 Geth 的存储结构设计与相关源码,介绍其数据库层次划分并详细分析各个层次中相应模块的核心功能。 以太坊作为全球最大的区块链平台,其主流客户端 Geth(Go-Ethereum)承担了绝大部分节点运行与状态管理的职责。Geth 的状态存储系统,是理解以太坊运行机制、优化节点性能、以及推动未来客户端创新的基础。 本文作者: po Web3buidler.tech Core Contributor, EthStorage Engineer Geth 底层数据库总览 自 Geth v1.9.0 版本起,Geth 将其数据库分为...

以太坊单独质押实战教程:手把手教你完成部署
内容丨Ray 编辑 & 排版丨Yewlne、环环 以太坊的单独质押(Solo Staking)是保护网络安全和去中心化的黄金标准。通过运行自己的验证者节点,您可以直接参与网络共识,获得完整的质押奖励,并保持对资金的完全控制。本教程将为您提供详细的指导,帮助您在家中部署以太坊单独质押节点,确保安全性和稳定性。前提概要首先,我们需要有这样的一个基本概念:要处理来自执行层的传入验证器存款,您需要运行执行客户端以及共识客户端。这意味着我们至少需要部署两个客户端程序(在本教程中,为三个,共识客户端按照功能进行了拆分)。如果想了解更多执行客户端和共识客户端的差异及功能职责,可以点击阅读: https://ethereum.org/zh/developers/docs/networking-layer/一、选择执行客户端以太坊生态的客户端种类非常丰富,执行客户端和共识客户端都有多种不同语言的实现,如使用 Go 语言实现的 Geth, 使用 Rust 语言实现的 Reth 等。你可以根据自己喜好,选择不同的客户端,整体流程是类似的,只是不同客户端实现涉及的命令不同。在这里,我们不能对所有的客户端...

重磅 | LXDAO 中文名正式从“良心 DAO”改为“蓝翔 DAO”!
撰文 | Bruce 编辑&排版 | Connie 图片 | Ache、Connie、Cikey重磅消息! LXDAO 今日起中文名正式从“良心 DAO”改为“蓝翔 DAO”! 让我们抓紧看看到底怎么个事儿——Web3 技术哪家强?中国就找 LXDAO!LXDAO 创办于 2022 年 6 月,至今已有快 2 年的历史,是由几位喜欢开源的开发者联合发起的一所现代化、综合性的产学研一体的 DAO 组织,主要从事 Web3 公共物品相关的教育、研发和维护。 LXDAO 以创办历史不太悠久,但实训项目齐全、师资力量雄厚、培养模式先进而闻名全国。LXDAO 超过一半的同学为程序员,是现代化 Web3 技师、高级技工的摇篮。学院概况LXDAO 现有 0 个校区(正在筹备在清迈四海搭建第一个线下校区)。我们主要在 Internet 远程学习和工作交流。面向全球 13810 个城市招生,不限语言、地区和种族,能同时容纳上百万人。 LXDAO 拥有丰富的实训项目,涵盖了 Web3 的多种主题,包括但不限于教育、公共物品、全链游戏、开源、开发者关系维护、商务合作等。 我们也跟许多国际单位联合开展一...
LXDAO 是一个专注研发的 DAO 组织,致力于构建支持有价值的公共物品和开源项目的无限循环。 LXDAO is an R&D-focused DAO dedicated to building an Infinite Cycle that supports valuable

Subscribe to LXDAO

Geth 源码系列:存储设计及实现
在区块链的世界中,状态存储是每一个节点的「记忆核心」 — — 它记录着亿万账户的余额、合约的代码、交易的痕迹,甚至决定着一笔交易能否被正确执行。作为以太坊生态的基石,Geth 客户端如何以精密的架构设计承载海量状态数据?其存储系统如何在性能、安全与可扩展性之间找到平衡? 这篇文章是 Geth 源码系列的第二篇,通过这个系列,我们将搭建一个研究 Geth 实现的框架,开发者可以根据这个框架深入自己感兴趣的部分研究。这个系列共有六篇文章,在这第二篇文章中,将系统讲解 Geth 的存储结构设计与相关源码,介绍其数据库层次划分并详细分析各个层次中相应模块的核心功能。 以太坊作为全球最大的区块链平台,其主流客户端 Geth(Go-Ethereum)承担了绝大部分节点运行与状态管理的职责。Geth 的状态存储系统,是理解以太坊运行机制、优化节点性能、以及推动未来客户端创新的基础。 本文作者: po Web3buidler.tech Core Contributor, EthStorage Engineer Geth 底层数据库总览 自 Geth v1.9.0 版本起,Geth 将其数据库分为...

以太坊单独质押实战教程:手把手教你完成部署
内容丨Ray 编辑 & 排版丨Yewlne、环环 以太坊的单独质押(Solo Staking)是保护网络安全和去中心化的黄金标准。通过运行自己的验证者节点,您可以直接参与网络共识,获得完整的质押奖励,并保持对资金的完全控制。本教程将为您提供详细的指导,帮助您在家中部署以太坊单独质押节点,确保安全性和稳定性。前提概要首先,我们需要有这样的一个基本概念:要处理来自执行层的传入验证器存款,您需要运行执行客户端以及共识客户端。这意味着我们至少需要部署两个客户端程序(在本教程中,为三个,共识客户端按照功能进行了拆分)。如果想了解更多执行客户端和共识客户端的差异及功能职责,可以点击阅读: https://ethereum.org/zh/developers/docs/networking-layer/一、选择执行客户端以太坊生态的客户端种类非常丰富,执行客户端和共识客户端都有多种不同语言的实现,如使用 Go 语言实现的 Geth, 使用 Rust 语言实现的 Reth 等。你可以根据自己喜好,选择不同的客户端,整体流程是类似的,只是不同客户端实现涉及的命令不同。在这里,我们不能对所有的客户端...

重磅 | LXDAO 中文名正式从“良心 DAO”改为“蓝翔 DAO”!
撰文 | Bruce 编辑&排版 | Connie 图片 | Ache、Connie、Cikey重磅消息! LXDAO 今日起中文名正式从“良心 DAO”改为“蓝翔 DAO”! 让我们抓紧看看到底怎么个事儿——Web3 技术哪家强?中国就找 LXDAO!LXDAO 创办于 2022 年 6 月,至今已有快 2 年的历史,是由几位喜欢开源的开发者联合发起的一所现代化、综合性的产学研一体的 DAO 组织,主要从事 Web3 公共物品相关的教育、研发和维护。 LXDAO 以创办历史不太悠久,但实训项目齐全、师资力量雄厚、培养模式先进而闻名全国。LXDAO 超过一半的同学为程序员,是现代化 Web3 技师、高级技工的摇篮。学院概况LXDAO 现有 0 个校区(正在筹备在清迈四海搭建第一个线下校区)。我们主要在 Internet 远程学习和工作交流。面向全球 13810 个城市招生,不限语言、地区和种族,能同时容纳上百万人。 LXDAO 拥有丰富的实训项目,涵盖了 Web3 的多种主题,包括但不限于教育、公共物品、全链游戏、开源、开发者关系维护、商务合作等。 我们也跟许多国际单位联合开展一...
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers


原作:Rachid.A
原文:
https://zhero-web-sec.github.io/research-and-things/nextjs-and-the-corrupt-middleware
本期文章由 LXDAO 成员 Yewlne 翻译。
译文正文 最近,我与化名为 inzo_ 的 Yasser Allam 决定联手开展研究。在讨论了多个潜在目标后,我们决定将焦点放在 Next.js
https://github.com/vercel/next.js
GitHub 上拥有 13 万 Stars,目前每周下载量超过 940 万次)。这是一个我非常熟悉的框架,与它有美好的创作经历,正如我之前的研究成果
https://zhero-web-sec.github.io/research-and-things/
所证明的那样。因此,本文中的"我们"自然指代我们两人。
Next.js 是一个基于 React 的全功能 JavaScript 框架,拥有丰富的特性 — — 是深入研究细节的理想场所。怀着信念、好奇与韧性,我们踏上旅程,探索那些鲜为人知的角落,寻找藏匿其中的宝藏。
不久之后,我们就在中间件中发现了一个重大问题。其影响范围广泛,所有版本均受影响,且利用此漏洞无需任何前置条件 — — 我们将很快进行详细展示。
Next.js 中间件
授权神器:宝藏级老代码
执行顺序与 middlewareInfo.name
授权神器:昨日已成诗,今朝更值得
/src 目录
最大递归深度
漏洞利用
绕过授权/重写
绕过 CSP
通过缓存投毒实现 DoS(What?)
澄清
安全公告 — CVE-2025–29927
免责声明
结语
中间件允许你在请求完成之前执行代码。然后,你可以根据传入的请求,通过重写、重定向、修改请求或响应头,或直接返回响应的方式来修改响应内容(摘自 Next.js 文档)。
作为一个完整的框架,Next.js 拥有自己的中间件(middleware) — — 这是一个重要且被广泛使用的特性。它的应用场景众多,其中最重要的包括:
路径重写(Path rewriting)
服务器端重定向(Server-side redirects)
向响应添加头信息(如 CSP 等)元素
最重要的是:身份验证(Authentication)和授权(Authorization)
中间件的一个常见用途是进行授权,这涉及基于特定条件来保护特定路径。
身份验证和授权:在授予对特定页面或 API 路由的访问权限之前,确保用户身份并检查会话 Cookie(Next.js 文档)。
示例:当用户尝试访问 /dashboard/admin 时,请求首先会通过中间件,中间件会检查用户的会话 cookie 是否有效以及是否具有必要的权限。如果验证通过,中间件便转发请求;否则,中间件会将用户重定向到登录页面:

正如一位伟人曾经说过的,”talk is cheap, show me the bug”,让我们避免过多的叙述,直接切入主题;我们在浏览框架的旧版本(v12.0.7)时,我们发现了这段代码
https://github.com/vercel/next.js/blob/v12.0.7/packages/next/server/next-server.ts
当 Next.js 应用程序使用中间件时,会调用 runMiddleware 函数。除了其主要功能外,该函数还会获取 x-middleware-subrequest 头部的值,并用它来判断是否应该应用中间件。该头部值会使用冒号(:)作为分隔符被拆分成列表,然后检查这个列表是否包含 middlewareInfo.name 值。这意味着,如果我们在请求中添加带有正确值的 x-middleware-subrequest 头部,那么中间件 — — 无论其用途如何 — — 将被完全忽略,请求将通过 NextResponse.next() 被转发,并且将完成到原始目的地的路径,而不受中间件的任何影响。这个头部及其值就像一把”万能钥匙”,可以绕过所有规则。此时我们已经意识到发现了一个惊人的问题,接下来需要完成最后几个拼图。
要让我们的”万能钥匙”生效,它的值必须包含 middlewareInfo.name,但这个值究竟是什么呢?
执行顺序与 middlewareInfo.name middlewareInfo.name 的值非常容易推测,它仅仅是中间件所在的路径。要了解这一点,我们需要简单了解一下中间件在旧版本中的配置方式。
首先,在 12.2 版本之前 — — 这个版本中中间件约定发生了变化 — — 文件必须命名为 _middleware.ts。此外,app 路由器(router)仅在 Next.js 的版本 13 中才引入。当时存在的唯一路由器是 pages 路由器,因此该文件必须放在 pages 文件夹内(特定于路由器)。
有了这些信息,我们就能推断出中间件的确切路径,从而猜测 x-middleware-subrequest 头部的值。这个值只是由目录名称(即当时存在的唯一路由器名称)和文件名组成,遵循当时以下划线开头的命名约定:
x-middleware-subrequest: pages/_middleware 当我们尝试绕过那些被配置为系统性地将访问尝试从 /dashboard/team/admin 重定向到 /dashboard 的中间件时:

成功了,我们侵入了 ⚔️
我们现在可以完全绕过中间件,从而绕过任何基于它的保护系统,最典型的就是授权,就像我们上面的例子。这个发现相当惊人,但还有其他需要考虑的点。
12.2 之前的版本允许嵌套路由在目录树的任何位置(从pages文件夹开始)放置一个或多个_middleware文件,并且它们有执行顺序,正如我们在从Web Archive中检索到的旧文档截图中所看到的:

这对我们的漏洞利用意味着什么?
可能性 = 路径中的层级数量
因此,要访问/dashboard/panel/admin(受中间件保护),middlewareInfo.name的值有三种可能性,相应地x-middleware-subrequest的值也有三种可能性:
pages/_middleware
或
pages/dashboard/_middleware
或
pages/dashboard/panel/_middleware
到目前为止,我们认为只有版本 13 之前的版本容易受到攻击,因为中间件已在源代码中被移动,并且我们还没有覆盖它的所有方面。我们推测维护者一定已经注意到了这个漏洞,并在版本 13 的重大更改之前修复了它,所以我们向框架维护者报告了这个漏洞并继续了我们的研究。
令我们大为惊讶的是,在最初发现后两天,我们发现所有版本的 Next.js — — 从版本 11.1.4 开始 — — 都存在漏洞! 代码不再位于同一位置,漏洞利用的逻辑也略有变化。
如前所述,从版本 12.2 开始,文件不再包含下划线,必须简单命名为 middleware.ts。此外,它不再位于 pages 文件夹中(这对我们来说很方便,因为从版本 13 开始,引入了 app 路由器,这本会使可能性加倍)。
With that in mind, the payload for the first versions starting with version 12.2 is very simple:
考虑到这一点,从版本 12.2 开始的第一个版本的有效负载非常简单:
x-middleware-subrequest: middleware
还需要考虑到 Next.js 提供了创建 /src 目录的可能性:
(Next.js documentation) 作为在项目根目录中拥有特殊 Next.js app 或 pages 目录的替代方法,Next.js 还支持将应用程序代码放在 src 目录下的常见模式。(Next.js 文档)
在这种情况下,payload 将是:
x-middleware-subrequest: src/middleware
因此,无论路径中有多少层级,总共只有两种可能性。这简化了针对相关版本的漏洞利用难度。
在最新版本中,它又有了一点变化(我们保证,最后一次)。
在更新的版本中,逻辑又略有变化,请看这段代码:

v15.1.7
和之前一样,系统会检索 x-middleware-subrequest 头部的值,并使用冒号作为分隔符形成一个列表。但这次,请求直接转发的条件 — — 即忽略中间件规则 — — 有所不同:
常量depth的值必须大于或等于常量 MAX_RECURSION_DEPTH 的值(即 5)。在赋值过程中,每当列表 subrequests(即由:分隔的头部值)中的某个值等于 params.name(即中间件的路径)时,常量depth就会增加 1。如前所述,这里只有两种可能性:middleware 或 src/middleware。
因此,为了绕过中间件,我们只需要在请求中添加以下头部/值:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
或
x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware
这段代码最初是用来做什么的?
这段代码似乎是为了防止递归请求陷入无限循环。
https://nextjs.org/blog/cve-2025-29927
既然我们知道您喜欢这类内容,这里有一些来自 Bug Bounty Program 的真实案例。
绕过授权/重写
在这个例子中,当我们尝试访问/admin/login时,收到404响应。从响应头中可以看出,中间件执行了路径重写,以防止未经授权或不适当的用户访问:

但使用我们的授权神器 :

我们可以毫无障碍地访问该端点,中间件被完全忽略。目标 Next.js 版本:15.1.7
绕过 CSP
这次网站使用中间件来设置 — — 除了其他功能外 — — CSP和cookie:

让我们绕过它:

Target next.js version: 15.0.3Target next.js 版本:15.0.3
注意: 请留意两个目标的payload差异,其中一个使用了src/目录,而另一个没有。
通过缓存投毒实现 DoS(What?)
是的,通过这个漏洞也可能实现缓存投毒 DoS 攻击。这显然不是我们首先要寻找的,但如果没有敏感路径受到保护,且没有更有趣的可利用点,那么某些情况可能会导致缓存投毒拒绝服务(CPDoS):
假设一个网站根据用户地理位置重写用户路径,添加(/en、/fr等),且没有在根路径(/)上提供页面或资源。如果我们绕过中间件,就会避开重写,最终到达根页面。由于开发者并未打算让用户访问根页面,因此没有提供相应页面,我们会得到404(或根据重写配置/类型不同,可能是500)。
如果该网站使用了缓存/CDN 系统,可能会强制缓存404响应,导致页面不可用,严重影响站点可用性。

澄清
自安全公告发布以来,我们收到了一些人的咨询,他们担心自己的应用程序安全,并且不太理解攻击的范围。需要明确的是,易受攻击的元素是中间件。如果您没有使用中间件(或至少没有将其用于敏感目的),那么无需担心(不过,请检查上面提到的 DoS 方面),因为绕过中间件不会绕过任何实际的安全机制。
否则,后果可能是灾难性的,我们建议您迅速实施安全公告中的指导措施。
补丁
对于 Next.js 15.x,此问题已在 15.2.3 中修复
对于 Next.js 14.x,此问题已在 14.2.25 中修复
对于 Next.js 版本 11.1.4 到 13.5.6,我们建议查阅以下解决方法。
解决方案
如果无法升级到安全版本,我们建议你阻止包含 x-middleware-subrequest 请求头的外部用户请求访问你的 Next.js 应用。
严重性
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N(严重程度:9.1/10,临界级)
https://github.com/vercel/next.js/security/advisories/GHSA-f82v-jwr5-mffw
在撰写本文时,部署在 Vercel 和 Netlify 上的应用显然已不再受此漏洞影响(更新:由于存在大量误报,Cloudflare 已将该规则调整为仅在用户主动启用时生效 — — 这些误报未能有效区分来自合法用户的请求与潜在攻击者的请求)。
https://x.com/nextjs/status/1903522002431857063
本研究发布仅用于教育目的,旨在帮助开发者理解问题的根本原因,或为研究人员 / 漏洞猎人在未来的研究工作中提供启发。本文作为安全公告的补充材料,提供了有关漏洞本质的进一步说明和澄清 — — 因为公告中已公开了导致该漏洞的请求头(以及相关的提交差异)。
我们明确声明不支持对本文进行任何不道德的使用。
正如本文所强调的,这个漏洞在 Next.js 源代码中已经存在了数年,随着中间件及其版本的演变而变化。任何软件都可能出现严重漏洞,但当它影响到最流行的框架之一时,就变得特别危险,可能对更广泛的生态系统造成严重后果。如前所述,在撰写本文时,Next.js 每周下载量接近 1000 万次。它广泛应用于从银行服务到区块链等关键领域。当漏洞影响到用户依赖的成熟功能(如授权和身份验证)时,风险就更大了。
Vercel 团队花了几天时间来解决这个漏洞,但值得注意的是,一旦他们意识到问题,修复就被提交、合并到几小时内实现到新版本中(包括向后移植)。
编译 | Yewlne
编辑 & 排版 | Yewlne、环环
原作:Rachid.A
原文:
https://zhero-web-sec.github.io/research-and-things/nextjs-and-the-corrupt-middleware
本期文章由 LXDAO 成员 Yewlne 翻译。
译文正文 最近,我与化名为 inzo_ 的 Yasser Allam 决定联手开展研究。在讨论了多个潜在目标后,我们决定将焦点放在 Next.js
https://github.com/vercel/next.js
GitHub 上拥有 13 万 Stars,目前每周下载量超过 940 万次)。这是一个我非常熟悉的框架,与它有美好的创作经历,正如我之前的研究成果
https://zhero-web-sec.github.io/research-and-things/
所证明的那样。因此,本文中的"我们"自然指代我们两人。
Next.js 是一个基于 React 的全功能 JavaScript 框架,拥有丰富的特性 — — 是深入研究细节的理想场所。怀着信念、好奇与韧性,我们踏上旅程,探索那些鲜为人知的角落,寻找藏匿其中的宝藏。
不久之后,我们就在中间件中发现了一个重大问题。其影响范围广泛,所有版本均受影响,且利用此漏洞无需任何前置条件 — — 我们将很快进行详细展示。
Next.js 中间件
授权神器:宝藏级老代码
执行顺序与 middlewareInfo.name
授权神器:昨日已成诗,今朝更值得
/src 目录
最大递归深度
漏洞利用
绕过授权/重写
绕过 CSP
通过缓存投毒实现 DoS(What?)
澄清
安全公告 — CVE-2025–29927
免责声明
结语
中间件允许你在请求完成之前执行代码。然后,你可以根据传入的请求,通过重写、重定向、修改请求或响应头,或直接返回响应的方式来修改响应内容(摘自 Next.js 文档)。
作为一个完整的框架,Next.js 拥有自己的中间件(middleware) — — 这是一个重要且被广泛使用的特性。它的应用场景众多,其中最重要的包括:
路径重写(Path rewriting)
服务器端重定向(Server-side redirects)
向响应添加头信息(如 CSP 等)元素
最重要的是:身份验证(Authentication)和授权(Authorization)
中间件的一个常见用途是进行授权,这涉及基于特定条件来保护特定路径。
身份验证和授权:在授予对特定页面或 API 路由的访问权限之前,确保用户身份并检查会话 Cookie(Next.js 文档)。
示例:当用户尝试访问 /dashboard/admin 时,请求首先会通过中间件,中间件会检查用户的会话 cookie 是否有效以及是否具有必要的权限。如果验证通过,中间件便转发请求;否则,中间件会将用户重定向到登录页面:

正如一位伟人曾经说过的,”talk is cheap, show me the bug”,让我们避免过多的叙述,直接切入主题;我们在浏览框架的旧版本(v12.0.7)时,我们发现了这段代码
https://github.com/vercel/next.js/blob/v12.0.7/packages/next/server/next-server.ts
当 Next.js 应用程序使用中间件时,会调用 runMiddleware 函数。除了其主要功能外,该函数还会获取 x-middleware-subrequest 头部的值,并用它来判断是否应该应用中间件。该头部值会使用冒号(:)作为分隔符被拆分成列表,然后检查这个列表是否包含 middlewareInfo.name 值。这意味着,如果我们在请求中添加带有正确值的 x-middleware-subrequest 头部,那么中间件 — — 无论其用途如何 — — 将被完全忽略,请求将通过 NextResponse.next() 被转发,并且将完成到原始目的地的路径,而不受中间件的任何影响。这个头部及其值就像一把”万能钥匙”,可以绕过所有规则。此时我们已经意识到发现了一个惊人的问题,接下来需要完成最后几个拼图。
要让我们的”万能钥匙”生效,它的值必须包含 middlewareInfo.name,但这个值究竟是什么呢?
执行顺序与 middlewareInfo.name middlewareInfo.name 的值非常容易推测,它仅仅是中间件所在的路径。要了解这一点,我们需要简单了解一下中间件在旧版本中的配置方式。
首先,在 12.2 版本之前 — — 这个版本中中间件约定发生了变化 — — 文件必须命名为 _middleware.ts。此外,app 路由器(router)仅在 Next.js 的版本 13 中才引入。当时存在的唯一路由器是 pages 路由器,因此该文件必须放在 pages 文件夹内(特定于路由器)。
有了这些信息,我们就能推断出中间件的确切路径,从而猜测 x-middleware-subrequest 头部的值。这个值只是由目录名称(即当时存在的唯一路由器名称)和文件名组成,遵循当时以下划线开头的命名约定:
x-middleware-subrequest: pages/_middleware 当我们尝试绕过那些被配置为系统性地将访问尝试从 /dashboard/team/admin 重定向到 /dashboard 的中间件时:

成功了,我们侵入了 ⚔️
我们现在可以完全绕过中间件,从而绕过任何基于它的保护系统,最典型的就是授权,就像我们上面的例子。这个发现相当惊人,但还有其他需要考虑的点。
12.2 之前的版本允许嵌套路由在目录树的任何位置(从pages文件夹开始)放置一个或多个_middleware文件,并且它们有执行顺序,正如我们在从Web Archive中检索到的旧文档截图中所看到的:

这对我们的漏洞利用意味着什么?
可能性 = 路径中的层级数量
因此,要访问/dashboard/panel/admin(受中间件保护),middlewareInfo.name的值有三种可能性,相应地x-middleware-subrequest的值也有三种可能性:
pages/_middleware
或
pages/dashboard/_middleware
或
pages/dashboard/panel/_middleware
到目前为止,我们认为只有版本 13 之前的版本容易受到攻击,因为中间件已在源代码中被移动,并且我们还没有覆盖它的所有方面。我们推测维护者一定已经注意到了这个漏洞,并在版本 13 的重大更改之前修复了它,所以我们向框架维护者报告了这个漏洞并继续了我们的研究。
令我们大为惊讶的是,在最初发现后两天,我们发现所有版本的 Next.js — — 从版本 11.1.4 开始 — — 都存在漏洞! 代码不再位于同一位置,漏洞利用的逻辑也略有变化。
如前所述,从版本 12.2 开始,文件不再包含下划线,必须简单命名为 middleware.ts。此外,它不再位于 pages 文件夹中(这对我们来说很方便,因为从版本 13 开始,引入了 app 路由器,这本会使可能性加倍)。
With that in mind, the payload for the first versions starting with version 12.2 is very simple:
考虑到这一点,从版本 12.2 开始的第一个版本的有效负载非常简单:
x-middleware-subrequest: middleware
还需要考虑到 Next.js 提供了创建 /src 目录的可能性:
(Next.js documentation) 作为在项目根目录中拥有特殊 Next.js app 或 pages 目录的替代方法,Next.js 还支持将应用程序代码放在 src 目录下的常见模式。(Next.js 文档)
在这种情况下,payload 将是:
x-middleware-subrequest: src/middleware
因此,无论路径中有多少层级,总共只有两种可能性。这简化了针对相关版本的漏洞利用难度。
在最新版本中,它又有了一点变化(我们保证,最后一次)。
在更新的版本中,逻辑又略有变化,请看这段代码:

v15.1.7
和之前一样,系统会检索 x-middleware-subrequest 头部的值,并使用冒号作为分隔符形成一个列表。但这次,请求直接转发的条件 — — 即忽略中间件规则 — — 有所不同:
常量depth的值必须大于或等于常量 MAX_RECURSION_DEPTH 的值(即 5)。在赋值过程中,每当列表 subrequests(即由:分隔的头部值)中的某个值等于 params.name(即中间件的路径)时,常量depth就会增加 1。如前所述,这里只有两种可能性:middleware 或 src/middleware。
因此,为了绕过中间件,我们只需要在请求中添加以下头部/值:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
或
x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware
这段代码最初是用来做什么的?
这段代码似乎是为了防止递归请求陷入无限循环。
https://nextjs.org/blog/cve-2025-29927
既然我们知道您喜欢这类内容,这里有一些来自 Bug Bounty Program 的真实案例。
绕过授权/重写
在这个例子中,当我们尝试访问/admin/login时,收到404响应。从响应头中可以看出,中间件执行了路径重写,以防止未经授权或不适当的用户访问:

但使用我们的授权神器 :

我们可以毫无障碍地访问该端点,中间件被完全忽略。目标 Next.js 版本:15.1.7
绕过 CSP
这次网站使用中间件来设置 — — 除了其他功能外 — — CSP和cookie:

让我们绕过它:

Target next.js version: 15.0.3Target next.js 版本:15.0.3
注意: 请留意两个目标的payload差异,其中一个使用了src/目录,而另一个没有。
通过缓存投毒实现 DoS(What?)
是的,通过这个漏洞也可能实现缓存投毒 DoS 攻击。这显然不是我们首先要寻找的,但如果没有敏感路径受到保护,且没有更有趣的可利用点,那么某些情况可能会导致缓存投毒拒绝服务(CPDoS):
假设一个网站根据用户地理位置重写用户路径,添加(/en、/fr等),且没有在根路径(/)上提供页面或资源。如果我们绕过中间件,就会避开重写,最终到达根页面。由于开发者并未打算让用户访问根页面,因此没有提供相应页面,我们会得到404(或根据重写配置/类型不同,可能是500)。
如果该网站使用了缓存/CDN 系统,可能会强制缓存404响应,导致页面不可用,严重影响站点可用性。

澄清
自安全公告发布以来,我们收到了一些人的咨询,他们担心自己的应用程序安全,并且不太理解攻击的范围。需要明确的是,易受攻击的元素是中间件。如果您没有使用中间件(或至少没有将其用于敏感目的),那么无需担心(不过,请检查上面提到的 DoS 方面),因为绕过中间件不会绕过任何实际的安全机制。
否则,后果可能是灾难性的,我们建议您迅速实施安全公告中的指导措施。
补丁
对于 Next.js 15.x,此问题已在 15.2.3 中修复
对于 Next.js 14.x,此问题已在 14.2.25 中修复
对于 Next.js 版本 11.1.4 到 13.5.6,我们建议查阅以下解决方法。
解决方案
如果无法升级到安全版本,我们建议你阻止包含 x-middleware-subrequest 请求头的外部用户请求访问你的 Next.js 应用。
严重性
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N(严重程度:9.1/10,临界级)
https://github.com/vercel/next.js/security/advisories/GHSA-f82v-jwr5-mffw
在撰写本文时,部署在 Vercel 和 Netlify 上的应用显然已不再受此漏洞影响(更新:由于存在大量误报,Cloudflare 已将该规则调整为仅在用户主动启用时生效 — — 这些误报未能有效区分来自合法用户的请求与潜在攻击者的请求)。
https://x.com/nextjs/status/1903522002431857063
本研究发布仅用于教育目的,旨在帮助开发者理解问题的根本原因,或为研究人员 / 漏洞猎人在未来的研究工作中提供启发。本文作为安全公告的补充材料,提供了有关漏洞本质的进一步说明和澄清 — — 因为公告中已公开了导致该漏洞的请求头(以及相关的提交差异)。
我们明确声明不支持对本文进行任何不道德的使用。
正如本文所强调的,这个漏洞在 Next.js 源代码中已经存在了数年,随着中间件及其版本的演变而变化。任何软件都可能出现严重漏洞,但当它影响到最流行的框架之一时,就变得特别危险,可能对更广泛的生态系统造成严重后果。如前所述,在撰写本文时,Next.js 每周下载量接近 1000 万次。它广泛应用于从银行服务到区块链等关键领域。当漏洞影响到用户依赖的成熟功能(如授权和身份验证)时,风险就更大了。
Vercel 团队花了几天时间来解决这个漏洞,但值得注意的是,一旦他们意识到问题,修复就被提交、合并到几小时内实现到新版本中(包括向后移植)。
编译 | Yewlne
编辑 & 排版 | Yewlne、环环
No activity yet