arthens / safe-translations
使用 Symfony Translations 时自动转义变量
Requires
- php: >=5.6.0
- symfony/translation: ~3|~4
- symfony/twig-bridge: ~3|~4
- twig/twig: ~2
Requires (Dev)
- phpunit/phpunit: ~3.7
This package is not auto-updated.
Last update: 2024-09-17 16:50:52 UTC
README
arthens/safe-translations
是在 Symfony Translations 之上的一层额外安全层。
兼容性
版本 1.0 仅适用于 PHP 7.* 和 Twig 2.*。
版本 0.4 是最后一个支持 PHP 5.* 和 Twig 1.* 的版本
问题所在
Twig 是一个出色的渲染库,它还非常适用于防止 XSS,因为所有输入都会自动转义。例如,如果你有一个以下模板
你好 %username%
并且用户将他们的用户名设置为
<script>alert();</script>
你可以安心,因为 Twig 会自动将其转义为
你好 <script>alert();</script>
这是无害的。
那么问题是什么呢?
问题是,当使用 Symfony Translations 时,你会失去这种保护。以下 Twig 模板
{% trans %}你好 %username%{% endtrans %}
使用不安全,因为 username
不会自动转义。你必须自己转义它
{% trans with {'%username%': username|e} %}你好 %username%{% endtrans %}
这意味着你的模板默认是不安全的,现在你必须记得每次使用变量时都要转义它们。这不是世界末日,但变量是否像 Twig 一样自动转义不是更好吗?
注意:此问题仅适用于标记。如果你使用 |trans
过滤器,那么你就没问题了,因为所有内容都会转义(除非你同时使用 |raw
,在这种情况下你就有问题)。参见 文档说明。
我的解决方案
arthens/safe-translations
定义了 2 个新的 Twig 标记: {% safetrans %}
和 {% safetranschoice %}
。它们的工作方式与 {% trans %}
和 {% transchoice %}
完全一样,但变量会自动转义
{% safetrans %}你好 %username%{% endsafetrans %}
将再次生成
你好 <script>alert();</script>
但如果你需要混合转义和未转义的变量(例如注入 HTML)怎么办?
你可以,只需使用 |unescaped
{% trans with {'%message%': message|unescaped} %}你好 %username%,管理员说: %message%{% endtrans %}
在这种情况下,username
被转义,而 message
没有被转义。
安装
- 将
arthens/safe-translations
添加到你的composer.json
。 - 在
Twig_Environment
中注册Arthens\SafeTranslation\Extension\SafeTransExtension
。
然后你就可以使用了(假设你已经配置了 Symfony Translations)。
常见问题解答
1. 如何在用 Twig 使用 Symfony Translations 时自动转义变量?
使用 {% safetrans %}
和 {% safetranschoice %}
。
2. safetrans
和 safetranschoice
支持哪些选项?
它们是建立在 Symfony Translations 之上的,并且支持完全相同的选项。参见 Symfony Translations
3. 我如何从模板中提取字符串?
使用标准的Symfony Extractor。在底层,arthens/safe-translations
扩展了 Symfony 的 TransNode
,这意味着从提取器的角度来看,trans
和 safetrans
没有区别。
4. 为什么我需要使用 |unescaped
?它不能从上下文中猜测出来吗?
目前还不能。Symfony 翻译和 Twig 非常不同,我找不到自动完成这个功能的方法。这可能在未来的版本中有所改变。欢迎提交拉取请求。
5. 这是否已准备好用于生产?
99designs 自 2013 年以来已在生产中使用它。