arthens/safe-translations

使用 Symfony Translations 时自动转义变量

1.2.0 2021-03-09 00:34 UTC

README

arthens/safe-translations 是在 Symfony Translations 之上的一层额外安全层。

Build Status

兼容性

版本 1.0 仅适用于 PHP 7.* 和 Twig 2.*。

版本 0.4 是最后一个支持 PHP 5.* 和 Twig 1.* 的版本

问题所在

Twig 是一个出色的渲染库,它还非常适用于防止 XSS,因为所有输入都会自动转义。例如,如果你有一个以下模板

你好 %username%

并且用户将他们的用户名设置为

<script>alert();</script>

你可以安心,因为 Twig 会自动将其转义为

你好 &lt;script&gt;alert();&lt;/script&gt;

这是无害的。

那么问题是什么呢?

问题是,当使用 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 %}

将再次生成

你好 &lt;script&gt;alert();&lt;/script&gt;

但如果你需要混合转义和未转义的变量(例如注入 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. safetranssafetranschoice 支持哪些选项?

它们是建立在 Symfony Translations 之上的,并且支持完全相同的选项。参见 Symfony Translations

3. 我如何从模板中提取字符串?

使用标准的Symfony Extractor。在底层,arthens/safe-translations 扩展了 Symfony 的 TransNode,这意味着从提取器的角度来看,transsafetrans 没有区别。

4. 为什么我需要使用 |unescaped?它不能从上下文中猜测出来吗?

目前还不能。Symfony 翻译和 Twig 非常不同,我找不到自动完成这个功能的方法。这可能在未来的版本中有所改变。欢迎提交拉取请求。

5. 这是否已准备好用于生产?

99designs 自 2013 年以来已在生产中使用它。