thinkphp 5.0.20 存在模板代码注入风险,核心是用户输入污染模板内容且thinktemplate引擎未禁用{php}标签、动态include等危险特性,结合assign()传参、{:}执行、缓存编译缺陷可导致rce。

定位 ThinkPHP 5.0.20 模板代码注入风险,核心是识别“模板内容被用户可控输入污染”+“模板引擎未禁用危险函数”的组合场景。该版本默认使用 ThinkTemplate 引擎,不启用严格沙箱,且支持 {php}...{/php}、{include file="xxx"}、{:function()} 等可执行 PHP 或动态加载的语法,一旦模板路径或输出内容由用户输入拼接,极易触发注入。
检查模板渲染是否接收用户可控参数
重点排查以下几类调用方式:
-
assign() 传入未经过滤的 GET/POST 值并直接在模板中使用
{:...}:例如控制器中写$this->assign('content', $_GET['t']);,模板里写{:$content},攻击者传?t=system('id')即可执行命令; -
动态 include 文件名由用户输入决定:如
{include file="$tpl_name"},且$tpl_name来自$_GET['page'],可构造?page=../../runtime/log/202610/xxx.php包含日志文件中的恶意 payload; -
使用
{php}...{/php}标签且内部逻辑拼接用户数据:虽然该标签在 5.0.x 中已标记为“不推荐”,但若项目仍启用(未禁用template.php中的'tag_lib_php' => true),且内容来自数据库或表单,就构成高危路径。
确认模板引擎配置是否关闭危险特性
打开 config/template.php(或应用级配置),检查关键项:
-
'tag_lib_php' => false:必须为false,否则{php}标签可用; -
'default_filter' => 'htmlspecialchars':确保默认输出过滤开启,避免 XSS 进而辅助模板注入(如通过 XSS 注入构造恶意模板语句); -
'layout_on' => true且 layout 模板固定:若 layout 被动态覆盖(如通过layout($_GET['l'])),则可能绕过主模板限制。
审计常见高危模板写法
在 view/ 目录下全局搜索以下模式:
-
{:后紧跟变量名且该变量来自用户输入(如{:$user_input}、{:I('get.name')}); -
{include file=后是变量而非字符串字面量(如{include file="$file"}); -
{php}标签块内出现echo、print、eval、system等函数调用,或拼接了$_超全局数组; - 模板中存在
{:dump(...)}、{:print_r(...)}等调试函数,且参数含用户数据——虽不直接 RCE,但可能泄露路径、类名,为后续利用铺路。
验证是否存在运行时模板编译漏洞
ThinkPHP 5.0.20 的模板缓存机制存在缺陷:若开启 'cache' => true,模板首次解析后会生成缓存文件(如 runtime/view/xxx.php)。若攻击者能控制原始模板内容(如通过富文本编辑器保存到数据库,再 {include file="db:content"} 渲染),就等于间接写入 PHP 代码到缓存文件。测试方法:
- 尝试提交一段含
<?php phpinfo(); ?>的内容到后台富文本字段; - 刷新对应前端页面,查看
runtime/view/下最新生成的缓存文件是否包含该 PHP 代码; - 若存在,说明模板编译过程未对源内容做剥离或转义,具备模板注入落地条件。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











