FlawOpen

flawopen.com/Incidents/angle-cross-platform-zero-day-december-2025

● Google / Apple · CVE-2025-14174 · December 2025 · CVSS 8.8 · 高危
安全研究 · FlawOpen

CVE-2025-14174:Chrome 的 ANGLE 漏洞与 Apple 的 CVE 引用

Google 确认 Chrome 的 ANGLE 漏洞已遭利用。Apple 将此 CVE 用于另一项 WebKit 内存初始化问题。

💡 通俗易懂的原理解析 (ELI5)

有人抄写表格时越过指定栏位,写入下一条记录,这可以说明越界访问。登记簿也可能把同一编号用于不同条目;编号相同不代表缺陷相同,更不能证明两个产品共享同一段易受攻击的代码。

核心概念与专有名词

ANGLE
Almost Native Graphics Layer Engine:谷歌的开源库,把 OpenGL ES 和 WebGL 调用转换为 Metal、Direct3D、Vulkan 等原生 API。
Metal 后端
ANGLE 中面向 Metal API 的部分。Google 将问题归于 Mac 版 Chrome 的 ANGLE,但未披露受影响函数或修复机制。
越界访问(CWE-787)
越界访问(CWE-119 / CWE-787):操作访问了预期缓冲区范围之外的内存。CWE-787 更具体地指越界写入;Google 未披露具体操作或根因。
受检算术
发生溢出时会报告、而不是悄悄回绕的整数运算,例如 Chromium 和 ANGLE 中的 base::CheckedNumeric。
零日漏洞
零日漏洞是在修复发布前已遭利用的漏洞。Google 确认 Chrome 的 ANGLE 问题已遭利用。Apple 在 iOS 26.2 公告中另行描述了涉及 WebKit 问题的定向攻击。

框架映射

事件演进时间线

2025-12-10

谷歌发布 macOS 版 Chrome 143.0.7499.110,并说明该 ANGLE 问题已存在在野利用(Chromium issue 466192044)。

2025-12-12

Apple 公告将 CVE-2025-14174 列为 WebKit 内存初始化问题,并另将 CVE-2025-43529 列为 WebKit 内存损坏问题。Apple 表示后者可能与定向利用有关;这不能证明其与 Chrome ANGLE 问题根因相同。CISA 将 CVE-2025-14174 加入 KEV。

攻击执行流程分解

步骤 1

构造的网页到达图形层

CVE 记录称,特制 HTML 页面可触发 Mac 版 Chrome 的 ANGLE 问题。CVSS 向量要求用户交互,因此受害者需打开攻击者控制的网页内容。

步骤 2

ANGLE 转换为 Metal

Google 指出 ANGLE 是 Chrome 中受影响的组件。公开公告未指出责任函数,也未称 WebKit 使用相同的易受攻击代码。

步骤 3

访问了缓冲区之外的内存

Google 描述了越界内存访问,但未说明读写类型、受影响缓冲区或根因。下方代码是通用示例,不是 ANGLE 源码或该 CVE 的复现。

步骤 4

被用于定向攻击

Google 确认 CVE-2025-14174 已遭利用。Apple 另行报告 WebKit 问题的定向利用,也在 WebKit 内存初始化条目中使用该 CVE。公开公告未确认 Chrome 与 WebKit 存在共同利用链。

源代码对比:漏洞与安全实现

Google 未公开函数级根因或补丁细节。这个通用 C++20 示例先验证偏移,再通过减法将请求长度与剩余容量比较以避免溢出。它不是该 CVE 的复现,也不是 ANGLE 的实际修复。

存在漏洞的实现
// 仅为通用示例;并非 ANGLE 源码,也不是 CVE-2025-14174 的实现。
bool copyRange(std::span<std::byte> destination,
               std::size_t offset,
               std::span<const std::byte> source)
{
    std::copy(source.begin(), source.end(), destination.begin() + offset);
    return true;
}
加固后的安全修复
// 仅为通用示例;并非 ANGLE 源码,也不是 CVE-2025-14174 的补丁。
bool copyRange(std::span<std::byte> destination,
               std::size_t offset,
               std::span<const std::byte> source)
{
    if (offset > destination.size() ||
        source.size() > destination.size() - offset) {
        return false;
    }

    std::copy(source.begin(), source.end(), destination.begin() + offset);
    return true;
}

工程与系统安全加固清单

参考来源