本文目录导读:

在 Twig 中,自动转义(Auto-Escaping) 是默认开启的安全机制,它会根据模板文件的扩展名自动选择合适的转义策略,以下是详细说明:
默认自动转义行为
Twig 会根据模板文件扩展名自动选择转义策略:
.html.twig→ HTML 转义.js.twig→ JavaScript 转义.css.twig→ CSS 转义.txt.twig→ 不转义
在代码中配置自动转义
启用/禁用自动转义
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
$loader = new FilesystemLoader('/path/to/templates');
$twig = new Environment($loader, [
'autoescape' => true, // 或 'html' 启用,false 禁用
]);
指定全局转义策略
$twig = new Environment($loader, [
'autoescape' => 'html', // HTML 转义
// 'autoescape' => 'js', // JavaScript 转义
// 'autoescape' => 'css', // CSS 转义
// 'autoescape' => 'url', // URL 转义
// 'autoescape' => false, // 禁用自动转义
]);
在模板中控制转义
raw 过滤器 - 关闭转义
{# 输出原始 HTML,不转义 #}
{{ user_input|raw }}
{# 对比:下面的会被转义 #}
{{ user_input }}
escape 过滤器 - 手动指定转义策略
{# HTML 转义(默认) #}
{{ user_input|e }}
{{ user_input|escape }}
{# JavaScript 转义 #}
{{ user_input|e('js') }}
{# CSS 转义 #}
{{ user_input|e('css') }}
{# URL 转义 #}
{{ user_input|e('url') }}
{# HTML 属性转义 #}
{{ user_input|e('html_attr') }}
autoescape 标签 - 控制代码块转义
{# 关闭转义 #}
{% autoescape false %}
{{ dangerous_html }}
{% endautoescape %}
{# 指定转义类型 #}
{% autoescape 'js' %}
{{ user_input }}
{% endautoescape %}
{# 恢复默认转义 #}
{% autoescape true %}
{{ user_input }}
{% endautoescape %}
完整示例
PHP 设置
$loader = new FilesystemLoader(__DIR__ . '/templates');
$twig = new Environment($loader, [
'autoescape' => 'html', // 全局 HTML 转义
'debug' => true,
]);
// 渲染模板
echo $twig->render('page.html.twig', [
'username' => '<script>alert("xss")</script>',
'html_content' => '<p>Safe HTML</p>',
'user_url' => 'javascript:alert(1)',
]);
Twig 模板 (page.html.twig)
<!DOCTYPE html>
<html>
<head>自动转义示例</title>
</head>
<body>
{# 自动转义 - 输出: <script>alert("xss")</script> #}
<p>用户名:{{ username }}</p>
{# 手动关闭转义 - 输出原始 HTML #}
<p>HTML内容:{{ html_content|raw }}</p>
{# 指定转义类型 #}
<p>URL转义:<a href="{{ user_url|e('url') }}">链接</a></p>
{# 复杂示例 - 包含变量 #}
<p>安全输出:{{ '<b>bold</b>' }}</p>
<p>raw输出:{{ '<b>bold</b>'|raw }}</p>
{# 使用 autoescape 标签 #}
{% autoescape 'html' %}
<p>这是安全的:{{ username }}</p>
{% endautoescape %}
{% autoescape false %}
<p>这是危险的:{{ username }}</p>
{% endautoescape %}
</body>
</html>
自定义转义策略
如果需要自定义转义规则:
use Twig\Extension\AbstractExtension;
use Twig\Environment;
class CustomEscapeExtension extends AbstractExtension
{
public function getEscapers()
{
return [
'custom' => function (Environment $env, $string, $charset) {
// 自定义转义逻辑
return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
},
];
}
}
// 注册扩展
$twig->addExtension(new CustomEscapeExtension());
// 模板中使用
{{ user_input|e('custom') }}
最佳实践
- 保持自动转义开启 - 这是防止 XSS 攻击的第一道防线
- 只在必要时关闭转义 - 使用
|raw时要确保内容是安全的 - 使用合适的转义策略 - 根据上下文(HTML、JS、CSS)选择正确的转义方式
- 避免嵌套引号问题 - 在 HTML 属性中使用
html_attr转义
自动转义是 Twig 安全性的重要特性,合理利用可以有效防止跨站脚本攻击(XSS)。