Twig 模板注入 ¶
约 812 个字 55 行代码 预计阅读时间 5 分钟
Twig is a modern template engine for PHP
Fast: Twig compiles templates down to plain optimized PHP code. The overhead compared to regular PHP code was reduced to the very minimum.
Secure: Twig has a sandbox mode to evaluate untrusted template code. This allows Twig to be used as a template language for applications where users may modify the template design.
Flexible: Twig is powered by a flexible lexer and parser. This allows the developer to define its own custom tags and filters, and create its own DSL.
基础语法 ¶
模板实际就是一个常规的文本文件,它可以生成任何基于文本的格式(HTML、XML、CSV、LaTeX 等
模板包含变量或表达,在评估编译模板时,这些带值的变量或表达式会被替换。还有一些控制模板逻辑的标签 tags。
Example
有两种形式的分隔符:{% ... %}
和 {{ ... }}
。前者用于执行语句,例如 for 循环,后者用于将表达式的结果输出到模板中。
twig 可以通过过滤器 filters 来修改模板中的变量。在过滤器中,变量与过滤器或多个过滤器之间使用 | 分隔,还可以在括号中加入可选参数。可以连接多个过滤器,一个过滤器的输出结果将用于下一个过滤器中。
上例会剥去字符串变量 name 中的 HTML 标签,然后将其转化为大写字母开头的格式。
Example
Twig 使用一个加载器 loader(Twig_Loader_Array)
来定位模板,以及一个环境变量 Twig_Environment 来存储配置信息。
其中,render() 方法通过其第一个参数载入模板,并通过第二个参数中的变量来渲染模板。
使用 Twig 模版引擎渲染页面,其中模版含有 {{name}}
变量,其模版变量值来自于 GET 请求参数$_GET["name"]
。
显然这段代码并没有什么问题,即使你想通过 name 参数传递一段 JavaScript 代码给服务端进行渲染,也许你会认为这里可以进行 XSS,但是由于模版引擎一般都默认对渲染的变量值进行编码和转义,所以并不会造成跨站脚本攻击 :
具体语法内容参考 twig 官方文档
Twig 模板注入 ¶
和其他的模板注入一样,Twig 模板注入也是发生在直接将用户输入作为模板,比如下面的代码:
Example
使用 map 过滤器 ¶
在 Twig 3.x 中,map 这个过滤器可以允许用户传递一个箭头函数,并将这个箭头函数应用于序列或映射的元素:
Example
Twig 3.x 会将其编译成:twig_array_map([0 => "Mark"], function ($__arg__) use ($context, $macros) { $context["arg"] = $__arg__; return ("hello " . ($context["arg"] ?? null))})
<?php function twig_array_map($array, $arrow)
{
$r = [];
foreach ($array as $k => $v) {
$r[$k] = $arrow($v, $k); // 直接将 $arrow 当做函数执行
}
return $r;
}?>
{{["id"]|map("system")}}
使用 sort 过滤器 ¶
sort 筛选器可以用来对数组排序
Example
类似于 map,模板编译的过程中会进入 twig_sort_filter 函数,其中 uasort 函数会调用用户传入的比较函数,如果控制了比较函数,就可以执行任意代码。
{{["id", 0]|sort("system")}}
大部分使用 arrow 的过滤器都可以用来执行任意代码,其余 payload 参考 TWIG 全版本通用 SSTI payloads
创建日期: 2024年7月22日 19:50:51