针对 CVE-2023-29689 的即装即用安全修复——修复 PyroCMS 3.9 中的服务器端模板注入(SSTI)漏洞,该漏洞可导致远程代码执行。
PyroCMS 允许管理员用户编辑存储在数据库中的模板。在没有沙箱隔离的情况下,拥有管理员权限的攻击者可以注入恶意的 Twig 代码:
{{['id']|map('system')|join}}
这会执行任意系统命令。上游维护者认为这“符合预期设计”,因为管理员用户是受信任的——但在多租户或企业环境中,“管理员”≠“可被信任授予 Shell 访问权限”。
该软件包会自动对用户可编辑的模板进行沙箱隔离,同时不限制合法的主题/插件模板。它利用 Twig 的 SourcePolicyInterface(由本软件包作者向上游贡献)来选择性地应用限制。
composer require ysaxon/pyrocms-ssti-fix
遗憾的是,由于 PyroCMS 禁用了自动发现,您需要自行添加 serviceProvider。
您可以通过以下命令完成:
sed -i "/App\\\Providers\\\AppServiceProvider::class,/a \ YSaxon\\\PyroCmsSstiFix\\\SandboxServiceProvider::class," config/app.php
SourcePolicyInterface)┌─────────────────────────────────────────────────────────────┐
│ Twig Render Request │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ StorageSourcePolicy │
│ │
│ Is template from storage path (database/user-editable)? │
│ │
│ YES ──────────────────► Enable Sandbox │
│ │ - Block: map, filter, reduce │
│ │ - Block: dangerous tags │
│ │ - Whitelist safe operations │
│ │
│ NO ───────────────────► No Sandbox │
│ (Theme/addon templates work │
│ normally) │
└─────────────────────────────────────────────────────────────┘
默认设置是安全的,适用于大多数安装场景。如需自定义:
php artisan vendor:publish --tag=pyrocms-ssti-fix-config
这将生成 config/pyrocms-ssti-fix.php:
return [
// Master switch
'enabled' => env('PYROCMS_SSTI_FIX_ENABLED', true),
// Override auto-detected storage path
'storage_path' => env('PYROCMS_SSTI_FIX_STORAGE_PATH', null),
// Customize allowed tags/filters/functions/methods/properties
'policy' => [
'tags' => [SecurityPolicyDefaults::INCLUDE_DEFAULTS],
'filters' => [SecurityPolicyDefaults::INCLUDE_DEFAULTS],
// ... see config file for full options
],
];
默认安全策略会阻止沙箱模板中使用以下危险特性:
map - {{['cmd']|map('system')}} 可执行 Shell 命令filter - 可调用任意 PHP 函数reduce - 可调用任意 PHP 函数include、extends、block、macro、import、embed、usesource - 读取任意文件内容include - 包含其他模板template_from_string - 从字符串创建模板沙箱模板中仍可使用以下安全操作:
{# Variables #}
{{ entry.title }}
{{ user.name|upper }}
{# Loops and conditionals #}
{% for item in items %}
{% if item.active %}
{{ item.name }}
{% endif %}
{% endfor %}
{# Safe filters #}
{{ text|escape }}
{{ date|date('Y-m-d') }}
{{ items|length }}
{{ name|lower|trim }}
{# Safe functions #}
{{ max(a, b) }}
{{ random(['red', 'blue', 'green']) }}
如果您的管理员模板确实需要额外功能:
// config/pyrocms-ssti-fix.php
'policy' => [
'filters' => [
SecurityPolicyDefaults::INCLUDE_DEFAULTS,
'my_custom_filter', // Add specific filter
],
'methods' => [
SecurityPolicyDefaults::INCLUDE_DEFAULTS,
'App\Models\Post' => ['getTitle', 'getSummary'],
],
],
安装后,请验证漏洞利用已被阻止:
{{['id']|map('system')|join}}修复前: 显示 id 命令的输出(或崩溃)
修复后: 显示错误或 [rendering failed: Filter "map" is not allowed.]
软件包无法找到 Twig。这通常意味着:
启用调试模式以查看详细信息:
PYROCMS_SSTI_FIX_DEBUG=true
如果管理员可编辑的模板使用了现已被阻止的功能:
该软件包会缓存所有路径检查以及方法/属性查找。在 auto 模式下,只有存储路径中的模板才会产生沙箱开销。
SourcePolicyInterface 贡献者MIT 许可证 - 请参阅 LICENSE 文件。