如何对模板输出进行转义
当我们从模板中生成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 <script>alert('helloe')</script> |
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') ?>'; |