一个参数串起文件读取与 RCE:Kaltura mwEmbed 未修复漏洞链深度解析

导语

一个看似普通的后端服务地址参数,为什么会同时演变成任意文件读取和远程代码执行?

2026 年 8 月 25 日,CERT/CC 公开了 Kaltura HTML5 Player Library(mwEmbed / html5lib)中的两项漏洞:CVE-2026-19913 与 CVE-2026-19912。两者都位于公开可访问的 mwEmbedLoader.php 调用链中,攻击者不需要账号、Cookie 或 Kaltura Session token。

真正值得开发团队关注的,不只是“又出现了两个高危 CVE”,而是这条漏洞链揭示了一种常见而危险的工程组合:应用允许用户影响服务器访问的目标地址,又把返回内容交给 PHP unserialize(),随后还使用外部输入构造缓存文件路径。每一处边界失守都在为下一处缺陷放大影响。

截至本文核验时间,CERT/CC 尚未获得 Kaltura 的厂商声明,也没有可安装的官方补丁。因此,受影响组织不能只等待升级包,而应立即缩小攻击面、增加入口和出口限制,并开展暴露面与入侵痕迹排查。


一、先把事实边界说清楚

已证实事实

  • CERT/CC 于 2026 年 8 月 25 日发布 VU#308749,确认 mwEmbed / html5lib 存在任意文件读取和远程代码执行漏洞。

  • CVE-2026-19913 的核心是:ServiceUrl 可接受攻击者控制的目标,包括非 HTTP(S) scheme;读取结果在反序列化失败时被写入错误信息并返回。

  • CVE-2026-19912 的核心是:攻击者可影响被反序列化的数据,同时 uiconf_id 被用于构造文件缓存路径且缺少充分约束;在默认文件缓存配置下,两者可组合为向 Web 可访问位置写入文件并实现代码执行。

  • CERT/CC 列出的受影响范围包括 html5lib v2.45、v2.103 及更早版本,以及其他暴露 mwEmbedLoader.php 的 v2.x 版本。

  • CERT/CC 表示未能联系到 Kaltura 完成协调;截至 8 月 27 日,厂商状态仍为 Unknown,未提供官方补丁。

  • 研究者在 Kaltura 2019 年发布的默认 Docker 镜像上完成了端到端 RCE 验证;对较新的 West-23.5.0 源码,研究者确认反序列化 sink 与路径构造问题仍存在,并单独验证了文件读取,但没有声称在该新版本上完成完整 RCE 链。

尚未证实或容易被误读的部分

  • 没有可靠一手来源确认该漏洞已被在野利用。 它也未因现实利用而进入 CISA KEV。

  • 研究者给出的 CVSS 3.1 评分为 9.1 和 10.0;截至核验时,NVD 页面尚未给出 NIST 的正式评分。文章不把研究者评分写成 NVD 评分。

  • 研究者通过搜索引擎看到 630 多个相关路径结果,这代表“疑似暴露组件的搜索结果”,不等于 630 台已确认可利用或已失陷主机。

  • 文件缓存是公开 RCE 链的重要条件。仅使用 Memcached 可能阻断该特定落盘路径,但不会修复不可信反序列化或任意文件读取。


二、为什么这个选题值得关注

mwEmbed 是一类很典型的遗留组件:主业务可能早已迁移到新播放器或新架构,但旧接口仍因历史页面、CDN 路径或兼容需求留在公网。它不一定出现在团队日常维护视野中,却仍继承主应用的文件权限、配置文件可见性和网络访问能力。

这类问题对 DevSecOps 有三点启示:

  1. 资产清单不能只覆盖主服务。 静态资源域名、旧版播放器、兼容 API 和历史子域名同样可能包含服务端代码。

  2. 漏洞影响来自组合,而非单一 CWE。 可控 URL、不安全反序列化、详细错误回显、路径穿越和可执行目录叠加后,影响会跨越多个安全边界。

  3. 无补丁场景考验纵深防御。 如果只能等待厂商修复,WAF、反向代理、网络出口策略、文件系统权限和运行时隔离是否能独立切断攻击链,就变得非常关键。


三、技术原理:一条链上的四次信任失误

公开研究定位到 KalturaClientBase::doQueue() 一类逻辑。为便于理解,可将关键过程抽象为:

$url = $config->serviceUrl . "/api_v3/index.php?service=";
$response = doHttpRequest($url, $params);
$result = @unserialize($response);

if ($result === false && serialize(false) !== $response) {
    throw new Exception("failed to unserialize server result\n" . $response);
}

以上是基于公开代码的简化表达,用于说明数据流,不应当作完整产品源码。

1. 用户输入影响服务器访问目标

ServiceUrl 本来用于指定后端 API 地址,但入口没有把它绑定到固定可信主机,也没有严格限制 scheme。于是,客户端输入不再只是“告诉应用查询哪个对象”,而是在影响“服务器去哪里取数据”。

这是 SSRF 类风险的典型起点:一旦服务器替攻击者发起请求,其本地文件、内网地址、云元数据和仅内部可达的管理接口都可能进入攻击面。

2. 远端返回值进入 PHP unserialize()

应用不是把响应当普通文本或 JSON 解析,而是交给 PHP 原生序列化机制。unserialize() 不只是数据解析器;当类加载与魔术方法等条件成立时,它可能实例化对象并触发额外行为。

因此,安全不变量应该是:只有来源可信、完整性可验证的数据才能进入原生对象反序列化。 仅检查内容格式远远不够。

3. 失败路径把原始内容返回给客户端

当目标指向本地普通文件时,内容通常不是合法序列化数据,解析会失败。问题在于,错误处理又把原始响应拼接进异常消息。结果是:原本可能“只”造成内部读取的缺陷,被错误回显转换成可直接观察的文件泄露。

这也是 CVE-2026-19913 的关键:数据已经越过服务器边界,而异常信息负责把它送回攻击者。

4. 外部输入再次参与缓存路径构造

公开研究显示,反序列化后的字段会进入文件缓存逻辑,而目标路径又受到 uiconf_id 影响。如果路径构造仅做字符串拼接,没有规范化后再检查目标是否仍处于允许目录内,目录穿越就可能把写入位置移出缓存目录。

当攻击者同时控制“写什么”和“写到哪里”,而目标目录又能执行 PHP 文件,任意文件写就可能升级为远程代码执行。这是 CVE-2026-19912 的核心组合条件。

整条链可以概括为:

外部参数影响请求目标
        ↓
服务器获取不可信内容
        ↓
PHP 原生反序列化
        ↓
失败时原文回显 → 任意文件读取
        ↓
对象字段进入缓存 + 路径可穿越
        ↓
写入 Web 可执行目录 → 远程代码执行

四、风险影响:不要只盯着 Web 进程权限

直接影响

  • 读取 Web 服务账号可访问的本地文件;

  • 泄露数据库连接串、管理口令、API 密钥、合作方密钥及内部主机信息;

  • 在满足文件缓存和 Web 执行条件时,以 Web 服务用户身份执行代码;

  • 进一步修改站点内容、窃取应用数据或建立持久化入口。

基于架构的风险推断

以下属于风险推断,而不是已披露攻击事实:

  • 若配置文件中存在可复用的数据库或管理凭据,攻击者可能从单一 Web 进程横向进入数据层或管理面;

  • 若 Kaltura 节点能访问内网 API 或云元数据,ServiceUrl 所代表的服务端取数能力可能扩大内部侦察面;

  • 共享基础设施中,如果租户隔离依赖应用层约束而非进程、文件系统和凭据隔离,单租户入口可能带来更大的影响半径。

是否能实现这些后续动作,取决于实际部署、权限、网络和凭据隔离情况,不能由 CVE 描述直接推定。


五、安全复现:只验证数据流,不构造真实利用载荷

不建议在公网实例上验证,更不应尝试写入 Web Shell。开发与安全团队可以在隔离环境中用最小模型检查两个安全不变量。

实验 A:错误信息是否泄露原始响应

创建一个仅包含测试字符串的 demo.txt,再用下面的本地 PHP 片段模拟“读取—反序列化—异常回显”流程:

<?php
$response = file_get_contents(__DIR__ . '/demo.txt');
$result = @unserialize($response);

if ($result === false && serialize(false) !== $response) {
    echo "解析失败,原始内容长度:" . strlen($response) . PHP_EOL;
    // 安全写法:不要输出 $response 本身
}

检查目标不是“复现泄密”,而是确认修复后的错误处理只返回固定错误码,并将详细信息写入受控日志,且日志本身做好脱敏。

实验 B:路径是否始终被限制在缓存目录

针对缓存键或 uiconf_id,编写单元测试验证:

  • 拒绝绝对路径、目录分隔符、空字节和编码后的穿越序列;

  • 路径规范化后,目标目录必须仍以规范化的缓存根目录开头;

  • 缓存目录位于 Web 根目录之外;

  • 即使发生错误,Web 服务器也不会执行缓存目录中的任何文件。

可采用“生成路径后再做目录包含校验”的断言,而不是只依靠对 ../ 的字符串替换。字符串黑名单很容易被编码、平台差异和路径规范化顺序绕过。


六、开发团队:怎样从代码上彻底切断漏洞链

以下为面向开发团队的建议。

P0:停止接收任意后端地址

  • 不再允许客户端直接提交完整 ServiceUrl;改为提交后端标识,由服务端映射到固定配置。

  • 如果业务确实需要动态地址,使用严格 allow-list,同时校验 scheme、主机、端口、DNS 解析结果和重定向后的最终地址。

  • 显式拒绝 file:gopher: 等非业务 scheme,并防止解析结果落入回环、链路本地和私网地址段。

P0:移除不可信 PHP 反序列化

  • 优先将接口响应改为 JSON 等纯数据格式,并用明确 schema 校验字段与类型。

  • 不要把 unserialize($data, ['allowed_classes' => false]) 当成完整修复;它能降低对象实例化风险,却不能解决任意读取、错误回显或路径穿越。

  • 如因兼容原因短期无法移除,至少必须同时保证来源固定、传输完整性可验证、响应大小受限,并禁止外部输入选择数据源。

P0:建立安全的缓存文件不变量

  • 缓存键使用服务端生成的不可逆 ID,而不是直接拼接用户输入;

  • 规范化目标路径,并验证其位于唯一允许的缓存根目录中;

  • 缓存目录放在 Web 根目录外,使用最小文件权限;

  • Web 服务器配置中显式禁止缓存和上传目录执行脚本。

P1:让异常处理保持“低信息”

  • 对外只返回稳定的错误码和请求追踪 ID;

  • 不返回上游响应、文件内容、绝对路径、堆栈、连接串或凭据;

  • 对内部日志做字段级脱敏,并限制读取权限和保留周期。


七、安全与运维团队:无补丁阶段的行动清单

以下为防护建议,并非厂商已发布的补丁方案。

P0:立即降低暴露面

  1. 盘点所有自托管 Kaltura、mwEmbed / html5lib、旧播放器域名和历史子域名。

  2. 在反向代理、WAF 或 CDN 上阻断外部访问 mwEmbedLoader.php;如业务必须使用,仅允许可信来源访问。

  3. ServiceUrl 实施固定域名 allow-list,并阻断非 HTTP(S) scheme、私网、回环和链路本地目标。

  4. 限制应用服务器出站网络,默认拒绝访问非业务目标。

  5. 在 Web 服务器层禁止缓存目录和上传目录执行 PHP。

P1:按“可能已泄露”开展排查

  • 搜索访问日志中携带 ServiceUrlmwEmbedLoader.php 请求;

  • 关注异常 scheme、非常规外部主机、编码后的路径穿越字符和异常长参数;

  • 排查 html5lib 缓存目录及 Web 根目录中的新建或修改 PHP 文件;

  • 检查 Web 进程异常出站连接、子进程启动和未知计划任务;

  • 若存在可疑访问,轮换 local.ini 及相关配置中的数据库、管理、API 与合作方凭据;

  • 凭据轮换应在隔离或重建受影响节点后进行,避免新凭据再次被窃取。

P2:把遗留组件纳入持续治理

  • 在外部攻击面管理中加入历史路径和静态资源域名;

  • 将服务器端 PHP、播放器组件、插件和容器镜像纳入 SBOM;

  • 为“可控 URL 进入网络客户端”“外部数据进入 unserialize()”“用户输入进入文件路径”建立 SAST/语义查询规则;

  • 在 CI 中增加负向测试:非允许 scheme、重定向到私网、路径穿越、错误回显和可执行缓存文件都必须失败。


八、从这个案例提炼三条代码安全原则

原则一:不要把 URL 当普通字符串

只要 URL 会被服务器访问,它就是一项网络权限委托。验证不能止于正则表达式,而应覆盖解析、DNS、重定向、最终地址与端口。

原则二:反序列化的安全取决于来源,而不只取决于格式

数据能否被解析,不代表它值得信任。原生对象反序列化的前提应是来源可信、内容完整性可验证,而且确有必要实例化对象。

原则三:文件写入必须同时约束内容、位置和执行属性

“只允许写缓存目录”不能停留在字符串拼接层面。目录应在 Web 根之外,路径应规范化并进行包含校验,运行环境还应从配置层禁止脚本执行。


总结

Kaltura mwEmbed 的两项漏洞提醒我们:重大安全事件往往不是由某一行“危险函数”单独造成,而是多个信任边界连续失守的结果。

在这条链中,ServiceUrl 让外部输入影响服务器的访问目标,unserialize() 把不可信响应升级为对象级风险,异常处理把内部内容送回客户端,缓存路径拼接又把数据控制变成位置控制。最终,一个参数入口串起了任意文件读取与远程代码执行。

对受影响组织而言,当前最重要的不是等待漏洞评分更新,而是确认接口是否暴露,并立即阻断入口、限制出站、禁止缓存目录执行脚本,再结合日志和文件完整性信息开展回溯。对研发团队而言,更长期的价值是把这些约束写成代码不变量与自动化测试,让任意一个环节的失误都无法独立完成整条攻击链。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值