React 和 Next.js 中的关键漏洞:您需要了解的一切

实验表明该漏洞利用成功率极高(接近100%),可实现完整的远程代码执行。攻击向量为未经身份验证的远程攻击,仅需向目标服务器发送精心构造的HTTP请求

 💬 251 条评论 |  React/Next.js | 

检测并缓解 React2Shell(CVE-2025-55182 和 CVE-2025-66478)—— React 和 Next.js 中的关键远程代码执行漏洞。组织应紧急打补丁。

简而言之:

  • CVE-2025-55182(React)和 CVE-2025-66478(Next.js)是存在于 React 服务器组件(RSC)“Flight”协议中的关键级未认证远程代码执行漏洞。
  • 默认配置存在漏洞——使用create-next-app创建并构建为生产环境的标准Next.js应用,无需开发者修改代码即可被利用。
  • 仅需精心构造的HTTP请求即可实现攻击。我们已构建出完全可用的RCE概念验证程序(暂不公开),测试显示其可靠性接近100%。
  • 漏洞源于RSC有效负载处理逻辑中的不安全反序列化,允许攻击者操控的数据影响服务器端执行。
  • 需立即修补漏洞。React和Next.js的强化版本已发布。
  • 数据显示,39%的云环境存在易受攻击的实例。
元素周期表

技术细节

React服务器组件(RSC)“Flight”协议中发现关键漏洞,影响React 19生态系统及采用该协议的框架(尤以Next.js为甚)。该漏洞已分配CVE编号:CVE-2025-55182(React)和CVE-2025-66478(Next.js),因序列化安全缺陷导致服务器端存在未经身份验证的远程代码执行(RCE)风险。该漏洞存在于受影响应用程序的默认配置中,意味着标准部署环境立即面临风险。鉴于其严重程度和易利用性,必须立即打补丁。

为在应用补丁期间保障生态系统安全,我们目前暂不披露具体细节;本文提供的信息仅用于协助防御者优先处理修复工作并理解风险。我们将随新信息披露持续更新本博客。

CVE-2025-55182 与 CVE-2025-66478 是什么?

CVE-2025-55182是React Server Components(RSC)使用的react-server包中存在的严重未认证远程代码执行(RCE)漏洞。

CVE-2025-66478是Next.js中对应的RCE漏洞,其通过实现RSC的“Flight”协议继承了相同底层缺陷。

该漏洞本质上存在于 react-server 包及其对 RSC “Flight” 协议的处理机制中。其特征为逻辑反序列化漏洞,服务器以不安全方式处理 RSC 有效负载。当服务器接收经过特殊构造的畸形有效负载时,会因结构验证失败,导致攻击者控制的数据影响服务器端执行逻辑,从而触发特权 JavaScript 代码执行。

实验表明该漏洞利用成功率极高(接近100%),可实现完整的远程代码执行。攻击向量为未经身份验证的远程攻击,仅需向目标服务器发送精心构造的HTTP请求。此漏洞影响主流框架的默认配置。

研究数据:云环境面临何种风险?

数据显示,39%的云环境存在易受CVE-2025-55182和/或CVE-2025-66478漏洞影响的Next.js或React实例。关于Next.js,该框架本身存在于69%的环境中。值得注意的是,其中61%的环境运行着公开应用程序,这意味着44%的云环境存在公开暴露的Next.js实例(无论运行版本如何)。

哪些产品受到影响?

受影响产品 已修复版本
react-server-dom*: 19.0.0, 19.1.0, 19.1.1, 19.2.0 19.0.1, 19.1.2, 19.2.1
Next.js: 14.3.0-canary, 15.x, 16.x (应用路由器) 14.3.0-canary.88, 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7

任何封装 react-server 实现的框架或库都可能受到影响。包括但不限于:

  • Next.js
  • Vite RSC 插件
  • Parcel RSC 插件
  • React Router RSC 预览版
  • RedwoodSDK
  • Waku

谷歌声明其Compute Engine提供的公共操作系统镜像默认不受影响。

安全团队应采取哪些措施?

1. 将 React 及其依赖项升级至强化版本(参见上文)。这是唯一有效的缓解措施。

2. 若使用其他支持 RSC 的框架(如 Redwood、Waku 等),请通过官方渠道确认捆绑版 react-server 的更新情况并立即升级。

共有 251 条讨论

  1. 该漏洞本质上是自RSC/服务器操作引入以来人们持续警告的最恶劣情况。

    服务器直接将客户端提供的不可信输入反序列化为模块+导出名称查找,随后执行客户端请求的任意操作(未验证metadata.name是否为自有属性)。

        return moduleExports[metadata.name]
    

    虽然可通过修补hasOwnProperty和强化反序列化机制缓解,但核心问题在于React从未真正承认其构建的是RPC层。观察gPRC或传统SOAP等真实RPC框架,它们均以模式定义、显式服务规范及配套工具集为起点,以防止边界混淆。React却反其道而行:API接口仅限打包工具可见的内容,而服务端点完全由客户端请求决定。

    我认为这种设计选择引发的安全隐患不会就此止步。原因并非React开发粗心,而是它试图解决的本应依赖显式规范而非魔法的领域。

    1. 在我看来这纯粹是不可原谅的疏忽,而非所谓“缺乏显式性”相较于gRPC等方案的缺陷。当你粗心到允许未经验证的用户输入在最后关头随意引用服务器命名空间中的任意对象时,显式模式根本无济于事。

      1. 但一旦做出这种特定的设计决策,问题发生只是时间问题。两者相辅相成。

        React实质上实现了一种伪装的RPC方案,这从其实现的功能类型就能明显看出——某些功能根本无法通过其他方式实现。但既然做了这个选择,就该承担责任并添加该机制所需的所有安全防护措施,事后再补救是行不通的。

        1. 我始终觉得服务器操作存在太多“魔法”

      2. 所有错误都可归咎于“疏忽”。但这无法改变某些设计本身更易出错且更不安全的本质。

    2. 该接口并非客户端随意请求即可访问,而是通过“use server”标记明确暴露给用户。设计者显然意识到这本质上是在构建RPC系统。

      其他RPC系统的实现也可能引入类似漏洞,并非此设计独有。

      (我参与React开发但未深度参与RSC)

      1. “use server”并非利用此漏洞的必要条件。

        1. 等等,我只用React做SPA(无服务器渲染)
          难道我也中招了?????

          1. 仅当你运行的是存在漏洞的Next.js服务器版本时才受影响。

          2. 不,除非你在服务器上运行React服务器组件运行时——而SPA根本不需要这样做,你只需提供静态包即可。

      2. 所以任何包都能声明某些模块为“use server”并使其可调用,无论RSC服务器所有者是否允许?这似乎不太理想。

        1. 该漏洞存在于受影响版本的传输机制中。即使未使用任何服务器组件/服务器函数,默认安装且未自定义代码的环境同样存在风险。

    3. 黑客如何利用此漏洞?我能在自己的网站上测试吗?

    4. 我们可修补hasOwnProperty并强化反序列化器,但存在更深层问题。React从未真正承认其构建的是RPC层。观察真正的RPC框架如gRPC甚至传统SOAP,它们都以模式定义、显式服务规范及一系列工具集为起点,以防止边界混淆。React却反其道而行:API接口仅限打包器可见范围,端点则完全取决于客户端请求。

      > 我猜测这种设计选择引发的安全隐患不会就此止步。原因并非 React 粗心大意,而是它试图解决的本应依赖显式规范而非魔法的传统问题范畴。

      现在我感到担忧,但我不使用 React。因此不得不问:SvelteKit 在这方面表现如何?

    5. 他们早有预警。这除了草率还能怎么形容?

      1. 随时随地调用任何代码,毫无限制也无防护措施。

        想象一下Meta公司的这些开发者:
        他们围坐桌前,同意调用eval()却不思考“可能出错的地方”

        1. 早在互联网普及之前,eval就被公认为极其危险。其危险性之高,以至于部署含eval代码的程序时,每次运行都该弹出醒目的闪烁警告。

          1. 半数网络地图解决方案依赖worker进程,这些进程无法从第三方源轻松加载,只能以blob形式加载。从blob加载worker本质上就是执行eval。

            1. 客户端的存在某种程度上就是为了被注入代码吧?

              1. 如果你要把文本标记描述成编程,那确实如此。但大多数人不会这么做。

          2. 嗯…这里用eval是不是比喻意义啊?

            你该去睡会儿了

            1. 不,他们的核心观点正是所做之事等同于直接调用eval。无论实际使用“eval”字面词还是名为eval的函数都无关紧要。

    6. > 服务器直接将客户端的不可信输入反序列化为

      要是我能为过去30年每次发现这种开头的严重漏洞赚一美元…

    7. 就像当年PHP服务器暴露源代码的旧时光

    8. 对普通用户而言,这是否意味着该方案及所有未采用它的方案都不安全?

      建立私有过时的仓库似乎也不太妥当。

      1. 并非如此。这并非说React或Next.js本身存在根本性安全隐患。

        问题在于这种特定的“执行客户端请求的任意服务器代码”模式。传统API采用固定接口时不会出现此类问题。

        1. 你是说执行客户端请求的任意服务器操作?我认为这种漏洞并非故意设计。

          1. 这种设计仅在动作定义极其清晰明确时才可行。至少需要验证请求是否合理、格式正确且符合当前上下文逻辑。

            1. 用Go等语言编写后端时也需要类似验证。我认为这在概念上并无本质区别。

        2. 我并非质疑其根本安全性。

          从架构层面看,基于强制依赖项的安全隐患,JavaScript整体正显现出日益扩大的攻击面。

          若React的基础框架及依赖项存在漏洞,React将直接或间接面临安全问题。

          这个明确存在的问题令人费解。如此基础的漏洞竟能长期存在?

          我再次从React和Next.js在JavaScript生态系统中的领导地位出发提出质疑。这种标准恐怕无人乐见。

          能否为LLM创建代码审查机制,使其能在发现漏洞后主动搜索相关问题?

          1. 公平地说,JavaScript庞大的攻击面始终存在。该语言运行于高度动态的环境中,从跨站脚本攻击(XSS)到后续各类漏洞,本质上都源于这种环境赋予的操作自由度。

            回想当年“mashups”技术,其核心正是利用了从任意远程服务器加载代码的能力——这些代码能与本地代码及他站代码并行运行,且所有代码间共享凭证。但想想看,让 Stripe 在你的域名上运行 stripe.js 确实很方便。AdSense 也是。Mixpanel 同样如此。既然如此,干脆让 npm 为单个依赖项目安装 1000 个包吧。这很糟糕。

    9. 确实相当糟糕。

      绝大多数开发者不会将框架更新至最新版本,因此这种情况将持续多年。尤其当你使用Next 12左右的版本时,若要升级到16+补丁版本,必然会遇到破坏性变更。

      另一方面,这对恶意行为者和渗透测试人员却是天大的好消息。

    10. > 它试图解决的是一类传统上需要显式处理而非魔法解决的问题。

      我长期以来基本持这种观点,能得到验证感觉挺开心的哈哈

  2. 来自Facebook/Meta:https://www.facebook.com/security/advisories/cve-2025-55182

    > React Server Components 版本 19.0.0、19.1.0、19.1.1 和 19.2.0 存在认证前远程代码执行漏洞,涉及以下包:react-server-dom-parcel、react-server-dom-turbopack 和 react-server-dom-webpack。漏洞代码存在不安全地反序列化HTTP请求中发往服务器函数端点的有效负载的问题。

    React官方声明:https://react.dev/blog/2025/12/03/critical-security-vulnerab

    React 服务器函数允许客户端调用服务器上的函数。React 提供了集成点和工具,供框架和打包工具使用,以帮助 React 代码在客户端和服务器端运行。React 将客户端请求转换为 HTTP 请求并转发至服务器。在服务器端,React 将 HTTP 请求转换为函数调用,并将所需数据返回给客户端。

    > 未认证攻击者可构造恶意 HTTP 请求发送至任意服务器函数端点,当 React 进行反序列化时,该请求可在服务器端实现远程代码执行。漏洞修复方案发布后将提供详细信息。

    1. 鉴于修复方案似乎是检查自有属性,攻击者很可能利用原型级模块属性或那个源源不断的礼物——即 __proto__。

      1. 这类漏洞我见多了。Java、Lua、JavaScript、Python等语言都存在。

        我认为依赖属性黑名单的反序列化机制是危险的赌博。

        在非专用的库中自行实现对象反序列化,其风险程度堪比编写自定义加密代码。

        1. 仅当反序列化对象具有行为时才存在风险。

      2. 并非__proto__而是constructor——若访问({}).constructor将获取对象构造函数,而在此基础上访问.constructor则会得到函数构造函数

        唯一未解的问题在于后续如何执行二次调用——仅能调用函数构造函数本身意义有限(尽管仍是严重缺陷)

    2. “React服务器函数允许客户端调用服务器端函数”

      这是故意的?这功能太可怕了

      1. > 故意的?

        这是RPC(远程过程调用)。这种方法最近在前端领域卷土重来。曾有tRPC;随后React凭借服务器组件的发布引发轰动;其他框架也开始效仿这种模式。我认为Svelte如今的“远程函数”也类似。Solid也在开发类似功能,因此SolidStart现在有了“use server”指令。它们可能并未复制React的协议,但调用服务器端函数的核心理念是相通的。

        1. > 近期在前端领域重新兴起的一种技术方案。

          这并非真正的“复兴”,RPC从未失宠。我们只是将其冠以“REST”之名——本质上仍是披着CRUD动词外衣的临时性JSON RPC格式,用于路由请求。

          1. 如果人们还愿意使用CRUD动词,而不是把所有操作都用POST解决

        2. RPC通常比这更明确,若不明确则属于Erlang那样的服务器间通信。

      2. 用于以类型安全的方式连接表单提交,至少这部分还说得通

        真正令人担忧的是这些漂亮的高级TypeScript框架背后,究竟藏着怎样的怪物才能让所有操作在JS中实现

  3. React开发团队为何执着投入精力打造这些徒增麻烦的复杂功能?这些功能不过是重复造轮子,解决的问题远少于制造的新问题。

    服务器端组件究竟比服务器端渲染(SSR)优越多少?除了微不足道的性能提升,它比客户端渲染(CR)究竟强在哪里?

    为何不投入更多精力修复钩子引入后急剧恶化的开发者体验?编译器虽已上线,却未效仿Svelte管理全局状态的方案,仅实现了备忘录机制?

    若能直接向React团队发消息,我会建议他们放弃现有计划,转而支持用户在组件逻辑中编写原生JavaScript控制流。

    抱歉发了牢骚。

    1. 服务器组件其实与SSR无关。

      我更倾向于将服务器组件视为组件化的BFF(前端后端)层。每个UI组件都关联着特定的“API”(无论是REST接口、GraphQL、RPC还是其他形式)。服务器组件让你能通过导入语法表达“后端组件”与“前端组件”之间的依赖关系,而非依赖`fetch`(客户端调用服务器)或<script>(服务器调用客户端)。当然你仍可保留API层,但这种方式提供了语法层面的表达方式,明确指出某个后端组件负责为特定前端组件准备数据。

      这解决了双方演进过程中的矛盾:每个后端组件始终准备着对应前端组件所需的精确数据,因为它们通过函数调用(更准确地说,是JSX)紧密绑定。这还允许你按需加载数据,且不会阻塞进程(当数据层延迟较低时尤为理想)。

      当然,你仍可选择传统REST API方案。但更可实现中间层的UI专属服务器计算。UI展示所需数据(视图模型)与数据存储方式(数据库模型)之间存在固有矛盾;RSC为你提供了一个放置UI专属逻辑的空间——这些逻辑应在后端执行,同时保留组件的组合优势。

      1. 感谢你的评论Dan,我始终珍视你文明理性的讨论态度,若我言辞稍显尖锐还请见谅。

        我理解这种逻辑,但仍存在若干疑虑:

        1 – 如前所述,SSR和API层已足够完善,在钩子开发体验仍如此欠缺的情况下重金投入RSC,在我看来颇为奇怪。React始终标榜自己是“纯JS框架”,但实际上你无法在组件中编写常规JS代码——钩子规则束缚了开发者,迫使他们采用特定的编码方式。

        2 – React向来以“无立场框架”著称,而RSC却在原本相距甚远的两层之间建立了深度耦合。

        以下功能更应由React提供:

        – 高级表单功能:与模型绑定并支持验证
        – 国际化支持:如Angular将翻译编译进应用,无需加载庞大的翻译JSON文件
        – 信号机制:实现真正的响应式状态管理
        – 更强大的控制流模板能力
        – 原生动画库
        这些功能至关重要,能让我不必为每个新项目学习时髦库的变体版本。

        1. 能否抽空聊聊我们的主救主VueJS?

        2. > React向来标榜自己是“纯JS框架”

          我从未听过有人说“React只是个JS框架”。他们只会说React用JSX替代模板。也说过React引入了函数式组件。但从未听过你所说的这种说法。

          > 但你实际上无法在组件中编写常规JS,因为钩子有太多规则,将开发者束缚在特定的编码方式中。

          这太离谱了。当然可以!你完全可以在组件中编写常规JS。我现在就能创建一个使用JS的组件(无论是否使用钩子)。你混淆了钩子的规则与使用JavaScript的能力。规则确实存在,但这并不意味着你无法编写JS。

          > 国际化方面,Angular将翻译内容编译到应用程序中,无需获取庞大的翻译JSON文件

          这是权衡取舍。现在每次更新都需要重新构建和部署。在React中我不存在这个问题。

          > 更优的控制流模板能力

          更优的模板?React使用JSX。难道你认为存在比if/else更优的控制流方式?

          > 信号机制,实现真正的响应式状态

          这在React社区已被争论到令人厌烦的地步,所有方案都有取舍。希望人们别再将其说成绝对真理。React的UI本质是状态的函数。单例模式将彻底颠覆React的现有思维模型。数据自上而下流转,这种改变必然伴随代价。

          1. 我曾听闻(尤其在React初创的头几年),编写React无需模板、编译器或特殊工具,“它就是纯JS”。

            当然你可以在组件内写任何代码,但这样会导致崩溃或性能崩溃。要正确编写组件,你不能使用任何状态管理的控制流,必须时刻记住哪些是正确的状态依赖关系,这使得组件20%是业务逻辑,80%是React逻辑。

            JSX中禁止使用if-else语句,仅允许表达式。因此你不得不编写难以阅读的嵌套三元运算,或借助JavaScript特例——让条件表达式返回最后一次真值评估结果。

            至于信号机制,Preact已成功应用且未引发问题。

            “状态函数”听起来很美妙,但其实早在React出现前很久就已解决——所有模板引擎本质上都是状态函数。真正的难点在于轻松组合状态,而这正是React始终未能实现的。

            1. > 编写 React 时无需模板引擎、编译器或特殊工具,“它就是纯粹的 JS”

              此观点依然成立。我目前确实未使用任何此类工具。编译器的存在并不意味着无法手写 JavaScript——这是完全不同的概念。况且他们筹划编译器方案已有数年之久。

              > 但随后它就崩溃了,或者性能糟糕透顶。

              你得说得更具体些。这句话我能套用到地球上所有编程语言/库上,没有具体情境的话它听起来都成立。

              > 你不能在JSX里用if-else,

              我根本不需要在JSX里用if-else控制流程。我可以写if(condition) return html;

              > 虽然这样写可读性差,或者利用JS特性的异常机制,比如让条件表达式返回最后一次真值评估结果。

              看我刚才写的句子。我完全可以不用模板就用if/else控制流程并提前返回。这有什么不理想的?

              > 关于信号机制,Preact在用,似乎也没搞砸什么。

              问题不在于字面意义上的“破坏”。他们若想实现信号机制完全可以做到。关键在于破坏了思维模型。

              在 React 中,数据自上而下流转。这虽是约束,但未必是坏事。我知道该向上寻找数据。引入信号机制后,这种认知彻底颠覆。现在不仅要关注组件通过 props/context 接收的数据(这些仍是向下的),还必须彻底改变思维模式。

              在接触 React 之前,我用了多年 Angular,但从未怀念过组件间需要通过多层横向传递数据的模式。

              > “状态函数”听起来很悦耳,但这个概念早在React出现前就已解决——所有模板引擎本质上都是状态函数。

              > “状态函数”听起来很悦耳,但这个概念早在React出现前就已解决——所有模板引擎本质上都是状态函数。真正的难点在于轻松组合状态,而React从未真正实现过这一点。

              这种说法极其误导(且错误)。模板无法组合,而React堪称组合之王。

              我开始怀疑你从未真正使用过React,而是基于他人(同样未实际使用过React)的言论形成观点。

      2. 作为偶尔需要开发Web应用的系统工程师,我深切体会到用动态语言构建REST API时,能打造出结构清晰、摆脱冗余且不稳定的模板层的应用是何等珍贵。去年我用RSC重构的Next应用,至今仍是自己开发过最清晰易维护的项目之一。

        至于这种魔力是否值得信赖,或者是否需要更明确的解决方案,我们拭目以待。但相较于编写仅限配套React应用使用的REST API,Next/RSC的体验显然更胜一筹,未来我仍希望继续使用它或类似方案。

        究其原因,“BFF”的REST API往往与前端紧密耦合,即便在系统架构中尝试分离,也无法在更高层次实现真正解耦。即使两部分能分离,但实际使用时必然相互依赖,这种分离反而可能形成不必要的障碍。

        1. 我的意思是Next应用的不同模块如今已清晰分离,但它们仍构成功能单元。前端与BFF的界限已消失,不过这种划分在小型应用中本就是错误的边界。

      3. 英雄之死或长生不老,终将目睹自己沦为恶棍。我耗费在调试钩子相关PR(包括自己的)上的时间简直难以估量,随后React竟将目光投向服务器端——这绝非我(我们大多数人?)所求;但我想,这正是Meta这家癌症公司所需。我可不需要。十五年来从未想过,如今竟会欣然承认自己正在使用名为Angular的企业级意大利面代码山。多年来我期盼着重返React项目,这份希望早已烟消云散。

    2. 完全赞同。作为另一位React开发者,我对React近年的选择深感遗憾。即便在新项目中,我也拒绝React集成式BFF层;钩子机制糟糕透顶,解决相关问题时整个框架变得愈发笨拙。

      我真正渴望的是能高效构建动态前端组件的优秀框架,但近几年React的99%开发成果都在制造冗余,让核心前端体验每况愈下。Hooks虽解决了组件元功能共享的难题,却让所有非平凡场景变得更糟;而RSC与并发特性似乎只会破坏现有体验、增加限制,而非带来任何改进。

      如果是在构建大型项目,这或许很酷,但对于更小的项目,React的使用体验简直痛苦不堪。我每天仍在使用它,但一旦找到适合产品的替代方案(类似但更简洁的方案),我就会立即切换。就我目前所知,对于现有项目而言,转向Preact和signals似乎是最佳选择。

    3. 真希望React不是那个“默认”框架。

      我同意Svelte和React采用的编译器模型确实提供了更愉悦的开发体验

      1. 个人认为Angular的开发体验堪称典范。过去十年间其API变更极少,由于框架立场鲜明,每个项目看起来都大同小异。

        而新增的功能?唯有提升开发体验之物

        1. > 过去十年间API变更极少

          但从1到2的迁移简直是场噩梦;人们恐怕至今仍心有余悸…

          1. 这段历程堪称惊心动魄,但必须承认Angular团队同样表现出色——他们为兼容旧版代码提供了长达v18版本的支持(不确定最新版本是否延续)。

            在单个项目中同时运行新旧版本Angular确实怪异,但最终一切都顺利解决了。

          2. 你说的没错。我因此基本不再使用任何谷歌支持的开源代码。

            我曾为大型项目选择Angular而非React[0],运行良好,但后来迁移到Angular 2时产生了大量无价值的工作。

            绝不再犯。

            即便Gemini多么优秀,我也不愿基于它开发任何东西——因为我无法信任谷歌不会再次突然撤资。

            [0] 我向来不喜欢JSX/TSX语法,也厌恶标记与代码混杂的风格,但后来学会了将就使用。

            1. 没人逼你立刻迁移。(再说,所谓无价值工作?难道重写为 TypeScript 就毫无价值?正因这次重写,该应用至今仍能升级到 Angular v21,未来多年也应如此。)

              React 也经历过多次剧烈更迭。(至今仍在更迭。) API稳定性的维持并无神奇的黄金周期。既无普适法则,也无项目特例。

              技术生态有时会经历相变。根据规模不同,这个过程可能相当漫长。Python 3发布于2008年,恰在Angular 1问世前一年;而Python 2的最后一次发布是2020年,比AngularJS的终版早了2-3年。(当然仍有大量企业运行在Py2环境下,我至少知道一家。)这类转变需要充足时间。

              Angular 1颇具主见,不愿延续“再加个jQuery插件”的传统做法。

              当时Miško在谷歌工作,他成功说服同事审视自己与Adam Abrons开发的框架。

              Angular 2于2014年1月发布。此后v1版本仍获得多年支持,甚至在1.5版本(约2016年?)将组件架构“回溯移植”至旧版。

              在v2+应用中,你可并行运行旧版v1代码直至v17版本。(至少v17文档完整描述了该流程,后续文档均链接至此页面。https://v17.angular.io/guide/upgrade )…

              个人认为谷歌做得相当不错。谷歌虽常放弃自家产品,但对开源项目相对宽容。(尽管AOSP的现状令人担忧。)

              1. > 谷歌会抛弃产品,但开源项目倒不至于。

                它放弃了Material Design web components项目,我记得这个项目曾吸引过Polymer团队成员。

                说到Polymer,它已演变为Lit;但据我所知谷歌不再支持该项目。Lit加入OpenJS基金会以维持运营。曾参与Lit和Material Design web components的谷歌员工大多已离职。

                还记得Workbox项目吗?那个简化服务工作器的方案?如今也奄奄一息。

              2. > 你不觉得重写为TS毫无价值吗?

                我向来不喜欢TypeScript,它丑陋、冗余且缺乏优雅。我绝非其拥趸。

                所以…不。

                但话说回来,有些战役你必须承认自己输了。TypeScript无处不在,几乎无处可逃。

                1. 我认为JS整体上仍比TypeScript更流行,但如果团队强制使用TypeScript的话,那确实如此。就像Java开发者不情愿地转向JS后,发现这需要更多冗余代码。

          3. 官方说法是1和2属于两个不同框架。后来改名为AngularJS和Angular正是为了避免混淆。

            Angular 1到2的迁移路径和React到Angular的迁移路径本质相同,只是用胶水粘合两个框架而已。

            而这个变更发生在十年前

            1. > 因此后来分别命名为AngularJS和Angular,以避免混淆。

              Angular.js和Angular?这根本不混淆啊 🙂

              1. 这——连谷歌搜索结果都乱套了

                应该更明确区分:例如“矩形框架 vs Angular框架”

            2. 承诺的轻松迁移从未兑现。Angular 2依然充斥着冗余代码。将AngularJS项目“迁移”到Angular 2,其工作量堪比移植到React或其他框架。

              所以没错,人们确实吃了亏(当初承诺过迁移路径),我再也不会依赖谷歌支持的UI框架了。

              1. > 我再也不会依赖谷歌支持的UI框架了。

                Lit其实挺不错 🙂 虽然它从未定位为框架。而且最近已从谷歌旗下独立出来。

        2. 我试过一次,感觉就像:加个按钮得改5个文件。

          1. 地球上所有公司的每个项目里都是那5个文件

            1. 指的是那些改用非ngModule方式的文件

        3. 我也赞同Angular如今体验很棒,但过去几年确实经历了重大API变更:独立组件、用esbuild替换WebPack、新控制流语法、新单元测试运行器等等…

          1. 正想说,我在工作中仅粗略浏览过相关项目的Angular代码,突然发现整个结构因ngModule弃用而彻底改变。庆幸自己没深陷其中。

      2. React已经足够优秀,很难找到强有力的理由去选择其他框架。

        1. 这是一种奇怪的哲学。

          生活中充斥着无数“足够好”的事物。

          我更青睐那些超越“足够好”的存在

    4. 我同意。即刻发表观点。

      依我之见,核心问题在于缺乏竞争(在实现方式上),而JavaScript自身的技术/语法限制又加剧了替代方案的匮乏。

      Vue、Svelte、Angular、Ripple——任何非React式JSX框架都需要定制编译器、专属文件格式和定制LSP/扩展才能运行。

      而 React/JSX 框架享有特殊待遇,预处理器本质上为 JSX 转换嵌入了粗糙的编译时宏机制。

      Rust 通过宏系统解决了这个问题,该系统无需外部预处理器即可实现语言扩展——例如 Yew 和 Leptos 实现了类似 Vue 和 React 的模式,包括在标准 .rs 文件中原生支持 JSX 和 HTML 模板,同时兼容标准测试工具和 LSP 支持;

      https://github.com/leptos-rs/leptos/blob/main/examples/count

      https://github.com/yewstack/yew/blob/master/examples/counter

      因此,要么ECMAScript团队想出办法实现标准化运行时与可编译的用户空间语言扩展(如宏),要么WASM为更适合该任务的语言铺平道路。

      然而这两种情况都不太可能发生,因此网络世界注定会继续保持非人体工学、过度复杂且低效的状态——至少在未来5到10年内如此。

      1. 好吧,我也有个极端观点。

        在我看来,React的核心功能(视图渲染)其实相当出色,这正是它难以被取代的原因。

        记得当初寻找DOM库时:

        – dojo:不合我意
        – prototype.js:不合我意

        – MooTools:不合我意
        – jQuery:终于找到中意的

        猜猜最终胜出的是哪个库?采用jQuery后,我彻底停止了寻找其他DOM库。

        但仍需模板渲染库:

        – Mustache.js:不合我意
        – Handlebars.js:不合我意
        – 嵌入式JavaScript模板:不合我意

        – XML配合XSLT:不适合我

        – AngularJS:极其厌恶它*

        – Knockout.js:不适合我

        – Backbone.js搭配模板引擎:不适合我,当时它正流行,我真心希望它消失**

        – React:真正让我中意的选择

        必须记住,React刚推出时还需JSX转译器,而当时连转译器本身都鲜有人用。我认为这比如今的障碍大得多。

        由此得出我的大胆观点:React核心确实优秀。我真心喜欢编写核心React/JSX代码,相信多数人也如此。若有人能打造更优的React,我认为你提到的那些问题不会阻碍其普及。

        问题往往出现在偏离React核心优势的领域。它的状态管理机制始终不够出色。虽然Redux本身并非React项目,但我仅凭阅读文档就深恶痛绝。而当前的RSC更是灾难——痛点层出不穷。

        我认为下一个创新点就在这里。我不认为会有人取代React或JSX本身来渲染模板。就像当年没人取代jQuery进行DOM操作——我们只是完全放弃了DOM操作。

        *我花了30分钟学习AngularJS,随即断言“这辈子再也不想碰这个库”。结果他们彻底放弃原有架构重写了Angular v2,看来我判断没错。

        **它最终销声匿迹,谢天谢地我逃过了学习Backbone.js的命运。

      2. 转译机制不解决这个问题吗?JSX不就是这么实现的吗?

        1. 转译除JSX之外的任何语言都需要复杂的工具链,包含LSP、编译器、IDE插件、打包插件等多层组件。

          采用这种路径的框架通常通过定义专用文件扩展名(.vue, .svelte)来激活工具链。

          这种定制工具链(LSP、IDE插件)给项目维护者带来巨大负担,使得创建可替代JSX生态系统的方案变得困难重重。

          例如Vue和Svelte都耗费数年才支持TypeScript,且集成方案脆弱不堪,常与测试工具存在兼容性问题。

          Angular的装饰器机制与本文所述原理高度相似——它本质是“有效”ECMAScript中的源代码注解,会被其专属编译器移除。尽管装饰器已被弃用,Angular项目仍需大量定制工具才能运行(例如尝试用自定义rspack配置构建Angular项目)。

          JSX/TSX 在这方面享有特殊待遇,因为它是 tsc 内置的宏——其他框架都不具备这种优势。

          1. 这是个先有鸡还是先有蛋的问题。JSX 之所以被支持,是因为它很流行。如果 React 决定推出新语法,我认为大家应该会 相当迅速 地适应并支持它。

          2. 这仅适用于TS而非JS吧?据我所知JSX并未获得Babel的特殊支持,但TSX确实如你所说有tsc支持。

    5. 服务器端组件究竟比SSR强在哪里?除了客户端渲染外,它能带来多少微不足道的性能提升?

      RSC是他们无法提升SSR速度时的权宜之计,同时试图减少客户端代码膨胀(同样失败了)

      1. 如果他们能像Svelte那样编译掉运行时,或像Angular那样部分编译,那么SSR运行速度或许会更快。

        1. SSR与CSR结合是两全其美的反面教材。当同一代码需同时处理SSR和CSR时,会导致脆弱的“等价”行为,不可避免的客户端“数据注入”错位及其他各类问题。同一代码既要积极但最小化地获取数据,又要使用并更新客户端的服务器端数据。

          最终这种所谓的“等构性”引发的问题远多于解决的问题。

          1. 听起来有点像钩子机制。

            这种短视的纯粹主义方法让所有人深陷布满陷阱的兔子洞。

          2. 尤其考虑到绝大多数网站要么采用客户端渲染的SPA,要么采用服务器渲染的多页面应用。多数网站根本不需要这种复杂性,但几乎所有JS框架却将其设为默认方案…

    6. 他们是在照顾客户需求。这些客户是缺乏服务器、后端和网络经验的前端开发者。他们希望运行能改变状态的代码,同时避免处理底层基础设施和复杂性,最好还能保持在“React状态”中。这正是Nextjs和RSC的吸引力所在。

    7. 因为Facebook拥有研发预算,相当于支付多名员工的薪资,而React是其最重要的技术资产之一。因此有人专门负责开发React的新功能和新版本,以此扩大Meta的护城河并提升股票价值。

      这种模式之所以奏效,在于它能让 React 开发者持续学习新特性,而非从事其他工作。这就像面向开发者的 SaaS 服务——只不过你支付的不是现金月费,而是人力时数月费。

    8. 我完全赞同。个人项目中我可能会从React转向ArrowJS这类框架:

      https://www.arrow-js.com/docs/

      它能轻松构建类似JSON的中心状态对象来表示页面内容,组件通过监听状态变化实现自动重渲染。这避免了Redux和Promise链的晦涩性——它们难以排查调试(除非添加浏览器扩展,但这本身就是代码异味)。

      我还听说Astro框架评价不错,它能封装其他框架(如React)编写的组件,从而避免完全重写:

      https://docs.astro.build/en/guides/imports/

      作为后端开发者,这完全超出了我的专业领域,所以如果有人知道我试图回忆的框架的实际名称(哈哈),请告诉我们。

      依我之见,React制造的问题远多于解决的问题:

        - 虚拟 DOM:不如直接动用 Facebook 的巨额预算修复浏览器 DOM,让它通过 GPU 实现 1000 fps 的渲染速度,再叠加备忘、缓存等技术,最后在上面堆砌 HTML 解析的冗余代码
        - Redux:根本没解决后端与前端之间的状态传输问题,比如 Firebase 就做到了
        - JSX:既然JavaScript已有模板字面量,我们真需要这个吗?
        - 路由:费尽心思实现永久链接,明明基于文件的URL三十年前就运作良好,当时浏览器就是MVC中的V
        - 组件:学习曲线陡峭(但为何如此?)且连类组件的钩子都懒得实现,反而将工作转嫁给用户——别告诉我们这很难,react-universal-hooks和react-hookable-component这类包早就实现了
        - 无休止的浏览器控制台警告:渲染改变状态及其他错误。只需设计能检测无限循环的单向数据流,这类场景就不可能发生
      

      就此打住。越了解React,越不喜欢它。这正是我判断新工具“空有其表”的主要依据之一。Ruby中那种“魔法约定胜于配置”的设计也让我有过类似体验。

      真正值得探索的方向——若我哪天中了互联网彩票(随着AI的到来这可能性微乎其微,毕竟应用销售和网站流量都将暴跌)——是分布式逻辑流。换言之,我构想的框架应让开发者编写单线程执行逻辑——该逻辑无需区分运行于后端或前端,并自动处理所有状态同步。理想状态下,它应优先采用Go语言那样的确定性分支/合并运行时,而非依赖承诺链的异步行为。其运作机制类似无冲突复制数据类型(CRDT)或软件事务内存(STM),但需完全符合原子性/一致性/隔离性/持久性(ACID)原则。如此我们终能回归在Node.js、PHP/Laravel等环境编写类似后端代码的体验,同时确保代码在浏览器中同样运行——即便用户网络中断,当重新连接时也能自动解决合并冲突。

      颇具讽刺意味的是,在接触Node.js前,我曾以为它本该如此运作——或许只需用@backend {}或@frontend {}注解包裹代码片段,便能自动分配运行环境。我从未料到它竟要经历如此繁复的折腾,才勉强支持浏览器中的模块导入!

      然而现实是,那些取得一定成就的框架维护者们,似乎都拔掉了身后的梯子,对现状几乎毫无改进。他们从不资助从第一性原理出发的团队,从不因批评既定规范而掀起波澜,只是加入其他应声虫的行列,将“我已得利”的福音传到最高金钱与政治层面。

      这种现状令人感觉开发者被迫奔赴天涯海角去迎合运行时环境,我甚至怀疑这还能算编程吗?这好比让人们在MS Word里手写低级RTF指令代码,而非直接用所见即所得编辑文档。我们集体丧失了理智…皇帝的新衣早已不复存在。

      1. ArrowJS官网单页HTML加载极其缓慢,光是页眉显示就耗费近一秒钟。

        1. 天啊我竟不知情!其实我还没实际用过呢哈哈。

          补充背景:我曾用8MHz的Mac Plus编写图形处理程序,因此对运行迟缓存在认知盲区。本质上,在如今GHz级计算机时代,任何东西都不该慢。所以多数延迟并非概念缺陷,而是实现效率低下。

          这些替代框架通常足够轻量,对其进行压力测试并贡献性能优化反而可能很有趣。尤其在AI加持下,我实在没理由再拖延了。

          编辑:思考两秒后,我怀疑问题其实出在后端请求上。它可能存在某些同步行为(这是我需要的),或是布局依赖问题迫使它必须等待所有响应到达才能渲染。这虽是更棘手的问题,但并非无法解决。这类问题尤其令我恼火,因为浏览器早在1990年代就基本解决了渐进式布局问题,而我们似乎遗忘了这门知识。

      2. > 既然JavaScript现在已有模板字面量,我们真的还需要这个吗?

        是啊?JSX远不止是模板功能。

        1. 但像htm这样的包本质上也在做同样的事,只是用的是带标签的模板。

      3. > 我在Ruby中也经历过类似情况,那种“魔法”约定胜过配置的设计理念。

        我不确定这指的是什么?真的是在说Rails吗?

        1. 是啊,我在一个老项目里用了Rails大概半年,里面充斥着太多魔术行为,导致我们根本无法有效追踪代码逻辑,连最简单的调试都要耗费数天。虽然正常流程基本运行良好,但当出错时,我们连最基础的代码疑问都无法解答,更别提进行故障评估了——因为在那个约定优先的代码库里,我们根本无法定位真正的根源。

          我来自C++背景,如今主要使用PHP/Laravel。尽管它不如Ruby的语法糖或.NET的底层优化“高效”,但我发现其缺乏魔法特性反而能带来更高的长期生产力。在我看来,Ruby似乎用糖衣解决最简单的问题,却对最棘手的问题视而不见。因此我始终无法看清它究竟解决了什么问题。

          总体而言,我认为这种“聪明”在2010年代曾风靡一时,如今已过时。更优的模式应类似Cordova或游戏脚本机制——由JavaScript/Lua等脚本语言驱动原生插件或Swift/Rust等语言编写的高性能引擎。更理想的是通过HTML或无代码媒体文件进行声明式驱动,这些文件能编码动画等复杂行为。

          当然,随着人工智能的兴起,这一切都将消亡。我预见未来将出现人类无法管理的、极其糟糕的代码库。或许当AI也束手无策时,我们甚至需要双人编程才能尝试修复问题。不过我对这类预测向来失准,但愿这次也是如此。

      4. Redux早已无人问津,其创建者甚至公开劝阻使用。这是过时的系统,将其列入问题清单只会让我觉得你既无React经验,也不懂自己在说什么(抛开技术空谈不谈,Redux作为产品仍实现了其设计目标,所以你的开发体验根本无关紧要)。

        在此语境下,Firebase 仅指数据库及其客户端/服务器端数据轮询机制。再次出现毫无意义的引用。

        1. 您好。我是当前 Redux 的维护者,自 2016 年中旬 Dan 将项目移交给我后便一直负责维护,距他创建 Redux 仅一年时间。值得一提的是,Dan从未在实际应用中使用过Redux(据我所知),而我多年来持续维护Redux和Redux Toolkit,并根据用户需求设计API。

          Redux至今仍是React应用中最广泛使用的状态管理库。其中确实存在部分遗留用法,但我们现代化的Redux Toolkit包每月下载量约达3000万次。Zustand作为客户端状态管理方案已广受欢迎,React Query也成为默认标准数据获取工具,但仅看RTK在NPM月下载量就足以证明其地位:

          https://npm-stat.com/charts.html?package=redux&package=%40re

          我曾多次探讨Redux诞生的初衷,其中哪些原因至今仍具现实意义,以及为何Redux至今仍是绿地项目中极具价值的选择:

          https://blog.isquaredsoftware.com/2024/07/presentations-why-

        2. 当老板正力推“Redux万物通吃”作为我们(React 17)代码库的 下一步 时,读到这篇真是解气…

  4. 我怀疑修复的提交是:

    https://github.com/facebook/react/commit/bbed0b0ee64b89353a4

    但该提交似乎被其他内容合并掩盖了,或者可能还存在其他问题。

    此模式出现4次,似乎是将暴露给“白名单”的函数数量减少。我推测这些模块在原型链中存在危险函数,且客户端能够调用它们。

          -  return moduleExports[metadata.name];
          +  if (hasOwnProperty.call(moduleExports, metadata.name)) {
          +    return moduleExports[metadata.name];
          +  }
          +  return (undefined: any);
    
    1. 鉴于该问题的严重性,我们已与众多行业合作伙伴协作,主动部署了缓解措施。

      我们仍强烈建议所有用户立即升级Next、React及其他React元框架(peer)依赖项。

      1. 这是否包含不受美国《云法案》管辖的供应商?此次漏洞披露时间线对我们欧洲人而言堪称噩梦——昨日傍晚才全面公开,而我已追溯到深夜发生的攻击日志。预计将引发连锁反应。

        我真心认为Next.JS是个优秀的框架,但作为欧洲开发者,当我负责的软件必须规避任何涉及《云法案》的内容时,你们这番表态无异于宣告:尽管Next.JS和React属于开源软件,它们已不再适合我使用。

    2. 我修复并重建了能处理的部分,并为此添加了自定义 Crowdsec WAF 规则,以防遗漏。

    1. 读来颇有意思。

      不过若我理解无误,你的PoC属于此处所述范畴:https://react2shell.com/

      > 任何需要开发者主动向客户端暴露危险功能的方案,均不构成有效PoC。常见伪PoC示例包括vm#runInThisContext、child_process#exec和fs#writeFile。

      > 这些仅在开发者刻意允许客户端调用时才可利用,且无论如何都存在安全隐患。真实漏洞不存在此限制。Next.js会自动管理服务器函数列表,其中并不包含这些函数。

      背景说明:此内容来自漏洞报告者Lachlan Davidson

    2. 我分别在未打补丁和已打补丁的react-server-dom-webpack环境下运行了你的exploit-rce-v4.js,两者均成功执行了RCE。

      因此我认为该机制描述可能有误,能否用真实的nextjs项目演示,而非模拟服务器?

      1. 我已更新代码,请用server-realistic.js测试:

        1. npm start 2. npm run exploit

      2. 正在尝试,Next.js机制略有不同——它在传递前会经过Proxy对象,导致RCE被阻断。

        目前正在调试,或许我的思路本就不对。

    3. 补充说明:作者刚刚(正确地)添加了免责声明,指出该PoC并不完全有效。

    4. 感谢这份技术文档,实在令人惊叹!

    5. 你这堆AI生成的垃圾削弱了对重大漏洞的响应力度。恭喜你。你的PoC无效,请立即删除。

      1. 联系我吧,slopcop.ai的自豪拥有者,早就想找机会大显身手了。

  5. Next.js/RSC 已成为新一代的 PHP 🙂

    看来今后会有更多机器人扫描网站中的 “/_next” 路径,而非传统的 “/wp-content”。

    1. 当客户端与服务器的界限如此模糊时,这种情况在所难免。UI库中的远程代码执行(RCE)可不是常听到的说法。

      1. 或许有天我们会回望JavaScript,得出这样的结论:每天向数十亿人推送未经审核的可执行代码,实乃一个巨大的错误。

        1. JavaScript本身没问题,问题在于人们用它构建什么以及如何构建。它从来不该成为系统级语言,但我们却执意要强行将其塑造成这样。

    2. 我已在部署环境中目睹多次针对此漏洞的攻击尝试。所幸昨晚及时发现并应用了补丁,但作为欧洲用户,在晚餐后才收到公告实在令人困扰。

  6. CVE 10.0评级对这么广泛使用的项目简直离谱

      1. 这个数字具有误导性,因为它未包含打包该依赖项的Next.js。实际使用场景中几乎都基于Next.js,仅有少数采用实验性React Router支持。

        1. 据我所知,该数字包含了传递性依赖项。因此当你执行 npm install next.js 时,其依赖树中所有组件的下载量都会被计入。

          此外,我认为这个数字很可能因持续集成管道等自动化下载而被夸大——数百或数千次下载可能仅对应实际环境中的单一实例。

          1. 这并非传递性依赖,而是直接打包在nextjs内部,我猜是为了避免构建过程中的脆弱性问题。

          2. CI管道缓存这些依赖有何不妥?这会造成巨大的计算和网络资源浪费。

            1. CI缓存依赖项确实很常见。但至少在某个阶段,CircleCI的缓存保存和恢复速度极其缓慢,直接下载所有依赖反而更快。总体而言,中小型项目安装所有依赖通常很快,带宽成本基本可忽略,因此许多项目不缓存依赖项很自然。

            2. 这类依赖通常会被消费数据中心的CDN缓存。甚至ISP也会缓存此类内容。

    1. 此类帖子的主题应将CVSS严重性标记为10.0,这样公关话术就无法轻易转移到“需要做什么”上。

      1. 遗憾的是,CVSS评分存在严重游戏化倾向。企业为漏洞赏金计划支付的奖金越高,漏洞猎手就越有动力夸大发现的影响。特别是CVSS v3的计算方式可能产生出人意料的超高或超低评分。

        虽然评分能有效引起关注,但我不建议用它来强制执行业务流程。即便安全扫描器对某个漏洞发出红色警报,你的代码很可能根本不受该CVE影响。

        1. 完全可以建立基于实际根本原因分析和影响评分的体系。

          令人惊讶的是,为何鲜少有人探讨此类解决方案,反而更多人刻意淡化CVSS的意义。

          仅淡化CVSS本身就可能被解读为公关话术,即便并非本意。

      2. 此案例中CVSS评分10.0或许合理,但众多其他评分存在严重虚高现象,导致评分体系价值大打折扣。

        1. 无论如何它仍能提供参考依据,总比毫无依据强。

          上述观点也可能被视为舆论引导——CVSS要如何更精准才能让你安心?

    2. React应用广泛,但React服务器组件使用率不高。

  7. 黑客如何利用漏洞?我想在自己的网站上测试

  8. 没有远程代码执行漏洞,Vercel就不叫Vercel。

  9. 我对JavaScript了解太少,甚至不知道React居然能在后端运行。我还以为它是前端框架呢?唉。

  10. 只要像正常人那样使用React就能避免这种情况…客户端渲染+配合Vite打包

  11. 时至今日,我仍不清楚React服务器端组件相较于传统渲染的HTML页面+使用HTMX究竟有何实质优势?

    要知道2017年React可是帮我付了房租。如今因其复杂性,我拒绝再碰React。

    1. >如今因其复杂性,我拒绝再碰React。

      那你现在喜欢用什么框架?

      1. 没错——你绝不能说复杂程度相当的应用中,HTMX比React更易理解。我曾处理过复杂的HTMX代码库,简直是噩梦。

        1. 没错——你绝不能说简单程度相当的应用中,React比HTMX更易理解。我处理过简单的React代码库,同样是噩梦。

          它们根本不针对相同的市场。

          1. 是啊…一个面向拥有数十万开发者的市场,这些开发者在该框架领域拥有丰富专业经验;另一个则面向一小撮Python开发者——他们拒绝学习JavaScript,直到有人把它藏起来并冠以“超媒体”之名。

            1. 以前也有几十万用PHP的 🙂 大多数开发者(约97.56%)水平糟糕/能力不足,随大流只会让你发现自己搭错了车 🙂

              1. 至今仍有数千开发者使用PHP…更不用说海量用户了… WordPress(占网络43%)、Facebook(数十亿用户)、维基百科(数十亿用户)……全靠PHP支撑。

                htmx不过是个玩具,玩起来略带趣味,却建立在不安全的根基上——它绕过浏览器基础安全机制,将一团JavaScript代码塞给后端开发者,而这些人懒得学习它,自以为更懂行……

                没有任何严肃项目会采用htmx,未来也绝不会采用,因为它在第三位开发者加入或开发进入第二年时就会变成无法维护的烂摊子。

                1. “没有任何严肃项目会采用[插入任意框架/语言/…],未来也绝不会采用,因为它在第三位开发者加入或开发进入第二年时就会变成无法维护的烂摊子” 前提是团队能力不足

    2. 它们赋予你代码运行时空的可选性。还能让你自由定义服务器/客户端的网络边界,并实现无缝跨界。

      承认不理解其优势完全没问题,但当人们断言它们毫无价值或纯粹增加复杂度时,实在令人恼火。在Web开发领域,没有任何系统能像RSCs这样为 开发者 提供更扎实的灵活性。我曾就此撰写过博客[0]。

      回答你的问题:htmx通过高度依赖服务器来解决这个问题。它无法在 你需要时 提供完整的客户端框架。而RSCs允许服务器与客户端共存,在保持双方完整功能的同时实现两者的简单组合。

      [0] https://saewitz.com/server-components-give-you-optionality

      1. 但当每次边界跨越都对安全性和性能产生重大影响时,实现无缝衔接是否明智?或许更应追求让边界尽可能简单清晰。

        1. 没错!在Next中很难理清哪些操作发生在服务器端、哪些发生在客户端,这使得安全性更难保障。

          虽然可通过代码实现清晰的分离来简化理解,但默认机制并不能有效强制执行。

      2. 技术上可行并不等于应该实施!

        核心批评在于:允许做不该做的事毫无益处,即便该系统实现了先前无法实现的功能。

    3. 你可选择增强功能并在客户端使用React。用HTMX实现这点虽可行(通过“islands”),但操作更繁琐——若试图跨页面共享客户端状态,你将陷入苦战。实际上HTMX方案存在诸多细节陷阱

      我的意思是它确实很复杂,但除非真正需要,否则最好别引入。这些方案确实能解决实际问题,唯一的问题是人们总想在所有场景都用它。我不用RSC,标准的单页应用对我项目就够用了,也更简单

    4. 更轻松/更具响应性,且无需API响应具备HTML可解析文本格式

  12. 这简直像试图用魔法函数将前端与后端神奇地连接起来——显然是个糟糕的主意。

    1. 这让我想起近期SvelteKit 远程函数 的GitHub讨论:

      > 即使在禁止客户端代码声明服务器功能的系统中(例如React服务器组件中的“use server”),经验丰富的开发者仍可能陷入陷阱。我们更倾向于强调远程函数的公开属性而非其服务器运行属性,并避免任何与词法作用域相关的混淆的设计方案。[0]

      [0] https://github.com/sveltejs/kit/discussions/13897

    2. 人们可能会觉得,此类设计唯一真正重要的非功能性要求就是绝对确保只能用“正确”的有效负载调用“正确”的函数。

    3. 说得对,这种事怎么可能提前数月就被预测并预警呢。

    4. 简历驱动的开发需要不断填充履历的新点子,无论创意好坏。结果就催生了这种东西

      1. 我认为金钱并非衡量创意质量的可靠指标。人工智能?区块链?犯罪活动?无数糟糕创意都赚得盆满钵满。

  13. 我对JavaScript不熟悉,所以试图理解这个概念。如果理解正确,这本质上是避免编写后端API并手动通过fetch或axios调用的方式——传统做法正是如此。以我基础的Java后端思维来看,最接近的类比是运行时通过反射动态生成API,而这种做法我绝不会采用… 我懒但不傻

    1. 这是RPC技术。已有半个世纪历史。Java诞生一年内就实现了RMI。[0]

      > 在远程过程调用系统中,必须先生成客户端存根代码并链接至客户端,才能执行远程过程调用。该代码可通过静态链接嵌入客户端,或通过动态链接机制从本地/网络文件系统调用库实现运行时加载。无论采用静态或动态链接,处理RPC的具体代码都必须以编译形式存在于客户端机器中…动态存根加载仅在所需存根代码缺失时启用。远程接口中定义的参数与返回类型同样通过此机制实现。将任意类加载至客户端或服务器存在潜在安全隐患;

      https://pdos.csail.mit.edu/archive/6.824-2009/papers/waldo-r

    2. 存在一类开发者(其规模在编程训练营兴起同期激增数倍,对此可自行评判),坚信在客户端与服务器端运行相同代码具有某种美德——尽管两者属于需求迥异的完全不同范式。此类现象正是可预见的后果。

      1. 公平地说,编程训练营的开发者们其实从未“认为这种架构具有优越性”,他们只是被要求使用这种方案并遵循既定模式。

      2. 这不过是二十年前.NET WebForms和Java JSF的翻版。两者都试图掩盖客户端与服务端的网络隔离,实际操作起来令人头疼。

        不知历史者注定重蹈覆辙,诸如此类。

      3. “前端后端都能跑JavaScript!”这句宣传语在我看来堪称史上最弱营销噱头。我见识过各种技术栈,网络应用采用何种语言根本不会限制开发便捷性。(况且理想状态下,前端本就该尽量少用JavaScript。) 几乎所有功能都能用更符合网络特性的方式实现,比如表单POST提交和HTML模板渲染。当然,谷歌地图或许可以做成胖客户端,但请相信我——并非每个电商网站都需要变成React泥潭。

        1. 我认为核心问题在于“标准”的演进速度无法及时解决输入验证和界面构建的大量痛点,这才催生出这种垃圾语言——它足够强大,能在几行代码里藏匿千百个陷阱。这种语言永远无法臻于完美,未来百年都将持续制造此类问题。

          倘若当初能循序渐进地扩展HTML标准,而非在内容流中植入功能完整的编程语言,网站与应用程序间将保持更佳一致性。我们本应将浏览器视为其本质:内容交付机制,而非应用程序开发平台。在我看来,这才是核心错误所在。

      4. 存在这样一类开发者(其规模在编程训练营兴起同期激增数倍,各位自行判断),他们坚信在客户端和服务器端运行相同代码具有某种美德,尽管这两者属于完全不同的范式且需求迥异。

        首先,“客户端和服务器运行相同代码”本身就是错误的。从什么时候起,响应式脚本(RSC)能在客户端和服务器两端运行了?

        更可笑的是,你居然认为跨范式使用相同语言是“编程训练营”的产物?难道像Blazor这样的技术是编程训练营催生的?

        你真做过Web应用开发吗?前后端都做过?你真经历过代码重复带来的痛苦吗?模型、验证逻辑、设计思路的重复?

        若你回答过这些问题却仍不明白消除代码重复的重要性,那我敢断言你绝对还在训练营阶段。

      1. 那你愿意具体说明一下是什么情况吗?

  14. 有人知道Tanstack Start为什么不受影响吗?

    1. TanStack Start 拥有独立的服务器函数实现:https://tanstack.com/start/latest/docs/framework/solid/guide…。它不使用 React 服务器函数,部分原因在于其设计初衷是与渲染框架无关(目前支持 React 和 Solid)。

      公平地说,他们甚至尚未发布(实验性)RSC 支持,或许这次只是碰巧时机巧妙。

  15. 这对Next.js和React团队实属难堪。多年来他们屡次被警告服务器-客户端通信方案存在风险,却嘲讽并无视所有非盲目赞誉者,如今终酿成此局。

    我认为他们作为JavaScript思想领袖的时代早已终结。

    1. 好奇而非批评:能否提供这些年针对该方案的警告链接?

      我对这段历史很感兴趣。

  16. 我很喜欢React。但RSC似乎不适用于离线优先的应用场景,是这样吗?

    1. RSC的核心特性之一是允许每个组件在服务器端或构建时独立获取数据。这意味着该特性可用于静态页面、离线应用等场景。但这与本次漏洞无关。

    2. 你不会在离线优先应用中使用它。但你完全可以在离线优先应用中使用它,实现起来甚至不难。

      我曾纯粹出于兴趣构建过完全离线的Electron应用,其中就完全采用了React服务器组件。

  17. Next框架仅因其静态构建功能而优秀,一旦停止支持该功能我就弃用。

  18. 是否有可供参考的漏洞利用示例?

      1. 这个概念验证不切实际,对Next.js生产环境构建无效。它需要用户显式暴露操作系统组件(如vm.runInContext),因此如https://react2shell.com所述无效

      2. 除非在create-next-app项目中演示成功,否则我绝不相信其有效性。

  19. React本身不可能存在远程代码执行漏洞。若漏洞出现在前端,则属于浏览器远程代码执行;若出现在后端,则如本例所示属于Next.js远程代码执行漏洞。

    1. 该漏洞存在于React Flight线缆协议内部,该协议被Next.js、Vite、Parcel、Waku及其他自定义RSC实现所采用。你的评论在2019年左右是准确的,但自React发布服务器组件后已不再成立。

    2. 你错了,但这正是该漏洞令人不安之处,也揭示了React的现状。直觉上人们会认为视图库不可能存在此类RCE漏洞,但React早已不是当初的模样。

    3. Next.js服务器运行的是React模块。尽管有人可能辩称Next.js不应打包存在漏洞的依赖项,但React如今确实提供了服务器端运行时模块,理应承担相应责任。

  20. 你真的需要React服务器组件甚至服务器端渲染吗?

    1. 在SSR出现之前(除非你使用的是PHP),你只能先发送一个网站的空壳,所有条件判断都只能在浏览器完全加载完HTML和JS之后才生效。若需调用API,渲染过程就会延迟数百毫秒甚至更久(往返服务器的时间)。

      而SSR技术下,若前端服务器与后端位于同一数据中心,服务器往返时间可缩短至个位数毫秒。更重要的是,你发送的是可立即渲染的实际内容HTML。

      真正的页面加载性能由此从秒级跃升至毫秒级,同时减少了网络传输数据量。尽管需要运行React服务器而非静态文件托管,但整体性能提升显著。

      1. 感谢指正。令人遗憾的是,在号称技术精湛的群体聚集的网站上竟需如此强调。

    2. 这完全取决于具体应用场景。

      在电商等领域,SSR堪称颠覆性技术;但在某些场景则毫无用武之地。

      RSC的优势则更复杂些——即便简单的作品集网站也能受益。与长期React开发者形成的普遍认知相反,RSC能大幅简化逻辑。将现有代码迁移到RSC可能相当棘手,对习惯React的开发者而言更是思维模式的重大转变。

    3. 没错。没有这些库,Web应用根本无法实现。

      1. 若你真这么认为,那我们恐怕正在倒退。

        1. 我认同他们的观点,在cgi-bin出现前,真正的Web应用几乎无法实现。服务器端渲染耗费十年才逐渐失宠。2000年代中期Flash网站和Gmail开始实现深度交互,标志着前端优先Web应用的开端,但即便这些应用仍需依赖后端提供初始数据集才能保证可用性能。

      2. 不,并非如此。它们需要更多服务器往返通信,且渲染结果难度更大。但若将浏览器视为智能终端,完全可以在服务器端运行应用程序,同时本地显示用户界面——这仅需定义额外基础操作即可。图形终端早在60年代就已问世。

    4. 当然如此,在特定场景下减少服务器往返次数就是更高效的解决方案

  21. 难以置信,完全出乎意料,居然从未有人指出RCS及其他多数软件存在缺陷。真的,完全没人提过。

  22. 我虽是React的忠实拥趸,但其服务器端设计实属重大失误。只要Next.js的统治者允许,React团队迟早会意识到这一点。

  23. CVE报告明确指出漏洞存在于React服务器组件,这强烈暗示这是后端(!!)而非客户端的远程代码执行漏洞。

    1. 我怀疑客户端开发者也受到影响——至少他们需要向依赖CVE报告的管理层解释这个远程代码执行漏洞。

    2. 还能在哪里?客户端的RCE到底意味着什么?

      1. 那不就是你自己机器上的RCE嘛 😀

      2. 这个术语向来模棱两可。但React普遍被视为客户端库,而客户端漏洞绝非新鲜事。跨站脚本攻击能形成独立研究领域,正是因为难以防止网站代码被恶意输入欺骗。

        你那句俏皮话在技术层面没错,但安全分析实在糟糕。依我看,看到这个标题的大多数人根本不会意识到需要审计服务器依赖项。

  24. 我敢打赌这漏洞几天内就会被利用,系好安全带!

  25. 修复了一个…还有无数个待处理…

    1. 这与“use server”无关。该语法用于标记服务器操作/服务器函数,在包含服务器组件的文件中未必会使用。

      1. 我认为存在关联。react.dev博客文章[1]指出该漏洞是

        > React解码发往服务器函数端点的有效负载时存在的缺陷

        而React服务器函数文档[2]明确说明

        > 服务器组件可通过“use server”指令[…]定义服务器函数;客户端组件可从使用该指令的文件中导入服务器函数

        因此该漏洞显然与React服务器函数相关,而服务器函数又与“use server”指令密切关联。

        [1] https://react.dev/blog/2025/12/03/critical-security-vulnerab

        [2] https://react.dev/reference/rsc/server-functions

        1. 不。你无法通过搜索“use server”之类的关键词来找出所有存在漏洞的代码。

          1. 这就是你所谓“与use server无关”的论据?

            这听起来像是他们强化指南里的原话。

          2. 我认为顶层评论是在批评整个由“use server”启用的功能(服务器函数)。漏洞存在于该功能中,所以(据我理解)你说的没错,用grep搜索“use server”找不到漏洞代码,但如果没有“use server”这个功能,漏洞就不会存在。

          3. 抱歉,你的理解有误。该CVE漏洞的本质机制正是如此——所有(且仅有)包含“use server”的代码都存在漏洞。

            1. 官方博客声明与此相悖:

              即使应用未实现任何React服务器函数接口,只要支持React服务器组件,仍可能存在漏洞。

              1. 哎呀,你说得对,是我疏忽了。任何能解析服务器函数的Flight服务器都存在漏洞,无论代码库是否实际使用了这些函数。这是传输机制层面的问题,而非RPC实现本身的问题。

    1. 这看起来不太真实。我不认为存在名为_next/static/chunks/react-flight的接口。

      1. > 不过TypeScript确实很棒。

        即便如此,这与核心问题无关。

          - 你需要选择包管理器,而每个人都有偏好:npm、yarn、bun、pnpm...
          - 你必须依赖npmjs.com获取依赖项,该平台恶意包数量远超其他依赖源
          - 你需要使用Next.js这类框架,它本身就是个充满向后不兼容变更的污池,还伴随着严重的安全隐患
        
        1. 使用Deno时,可从任意URL(包括自有仓库)更安全地获取依赖项。您还能为运行时设置权限,不过这未必能完全规避漏洞利用风险。

          最安全的做法或许是将所有依赖项嵌入源代码,并在每次发布时重新审核。但Deno允许我自主选择注册表,这点令人欣慰。

          Bun同样支持此功能,但感觉更像是后期附加的方案,而非基于安全考量设计的早期架构决策。

          1. > 使用Deno可更安全地获取依赖项

            Deno如何能防止React+Next.js的远程代码执行漏洞?

            1. 无法阻止。我回应的是你对TypeScript生态系统更广泛的担忧。

              避免RCE的关键在于认识到React(以及近期Vercel的)管理存在严重缺陷,你应当选择维护更负责任的优质工具。

              令我困扰的是,React表面上只是视图库,对多数使用者而言确实如此… 但它如今已演变为远超浏览器范畴的框架,暗藏着各种乍看之下完全难以察觉的安全隐患。大量使用Next的开发者可能根本不了解该框架的安全影响,更不清楚React在其中扮演的角色。这简直是一团乱麻。

              Deno绝对无法解决这个问题。

      2. …如果你的基准是JavaScript的话。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

你也许感兴趣的: