如何对模板输出进行转义

3.4 版本
维护中的版本

当我们从模板中生成HTML时,总会有风险存在,比如一些模板变量可能输出一些意外的HTML或者危险的客户端代码。结果这些动态内容会打破结果页面的HTML或者允许一些恶意的访问者执行一些页面攻击(XSS- Cross Site Scripting)。举个例子:

1
Hello {{ name }}
1
Hello <?php echo $name ?>

你想象一下这个用户输入下面的代码:

1
<script>alert('hello!')</script>

如果没有任何的转义,此模板会导致弹出一个js警告框

1
Hello <script>alert('hello!')</script>

这种情况看上去,没多大害处,但是如果一个用户知道这一步,它完全有能力写一个javascript在我们未知的安全区域来执行一些恶意行为。

这个问题的解决办法是输出安全转义。 如果添加了输出安全转义,同样的模板会渲染出无害的内容,script标签会作为普通文本输出到屏幕上。

1
Hello &lt;script&gt;alert('helloe')&lt;/script&gt;

PHP和Twig模板化系统采用了不同的方式来解决这个问题。如果你使用Twig,默认情况下是输出安全转义的,你的输出是受到保护的。如果是PHP,则输出安全转义不是自动的,需要你手工的进行处理。

Twig中的输出转义 

如果你使用Twig模板,那么输出转义是默认的。你不需要对用户提交的输出内容进行手动保护。

在某些情况下,你需要关闭输出转义保护,当你渲染某个可信变量或者包含某个标签时。假设管理员用户可以编写一些代码有HTML标签的文章。默认情况下,Twig将转义文章体。

为了渲染正常,需要添加一个raw 变量调节器:

1
{{ article.body|raw }}

你也可以在{% block %}区域或者整个模板中关闭输出转义。想了解更多,请参见Twig文档Output Escaping

PHP中输出转义 

在PHP中安全输出保护不是自动完成的,这就意味着除非你显示的选择来对某个输出变量进行保护,否则输出都是不安全的。我们使用view的方法escape()来对输出变量进行安全输出保护:

1
Hello <?php echo $view->escape($name) ?>

默认情况下,escape()方法默认情况下假设变量是被渲染在一个HTML上下文中的。也就是说只针对HTML安全。 它的第二个参数让你能够改变它针对的上下文。比如需要在javascript上下文中输出某些东西,就是用 js 上下文。

1
var myMsg = 'Hello <?php echo $view->escape($name, 'js') ?>';

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)