0

我正在使用PlayFramework2,但找不到正确处理 HTML 转义的方法。

在模板系统中,默认情况下会过滤 HTML 实体。
但是当我将 REST 请求与Backbone.js一起使用时,我的 JSON 对象不会被过滤。

play.libs.Json.toJson(myModel)用来将Object转换为String
所以,在我的控制器中,我return ok(Json.toJson(myModel));用来发送响应......但在这里,我的模型的属性是不安全的。
我找不到处理它的方法...

第二个问题:
模板引擎默认过滤 HTML 实体,这意味着我们必须将原始用户输入存储到我们的数据库中。
这是一种保存行为吗?

第三个问题: PlayFramework
中是否有手动转义字符串的功能?我能找到的所有这些都需要添加新的依赖项。

谢谢 !

编辑:我在Backbone.js模板级别找到了一种方法: - 使用myBackboneModel.escape('attr');而不是myBackboneModel.get('attr');
Underscore.js模板系统还包括该选项:<%= attr %>在不转义的情况下呈现,但<%- attr %>在转义时呈现!
请注意效率,每次渲染时都会重新转义字符串。这就是为什么应该首选 Backbone .create() 的原因。

4

1 回答 1

3

XSS 攻击预防的最佳实践通常建议您推理输出而不是输入。这背后有很多原因。在我看来,最重要的是:

  • 除非您确切知道将如何输出/呈现数据,否则对转义某些内容进行推理是没有任何意义的。因为不同的渲染方式需要不同的转义策略,例如正确转义的 HTML 字符串不足以在 Javascript 块中使用它。需求和技术不断变化,今天您以一种方式呈现数据 - 明天您可能会使用另一种方式(假设您将在不需要 HTML 转义的移动客户端上工作,因为它根本不使用 HTML渲染数据)您只能在渲染数据时确定正确的转义策略。这就是现代框架将转义委托给模板引擎的原因。我建议查看以下文章:XSS(跨站点脚本)预防备忘单
  • 转义用户的输入实际上是一种破坏性/有损的操作——如果你在将用户的输入持久化到存储之前转义用户的输入,你将永远不会发现他的原始输入是什么。没有确定的方法可以“取消转义”HTML 转义字符串,请考虑上面的移动客户端示例。

这就是为什么我认为正确的方法是将转义委托给您的模板引擎(即您用于 Backbone 的 Play 和 JS 模板引擎)。无需将您序列化为 JSON 的 HTML 转义字符串。请注意,在幕后 JSON-serializer 将对您的字符串进行 JSON 转义,例如,如果您的字符串中有一个引号,它将被正确转义以确保生成的 JSON 是正确的,因为它毕竟是一个 JSON 序列化程序,这就是它只关心正确的原因JSON渲染,它对HTML一无所知(它不应该)。但是,当您在客户端呈现 JSON 数据时,您应该使用您用于 Backbone 的 JS 模板引擎提供的功能正确地对其进行 HTML 转义。

回答另一个问题:您可以使用play.api.templates.HtmlFormat手动转义原始 HTML 字符串:

import play.api.templates.HtmlFormat
...
HtmlFormat.escape("<b>hello</b>").toString()
// -> &lt;b&gt;hello&lt;/b&gt;

如果你真的需要让 JSON 编码器转义某些 HTML 字符串,一个好主意可能是为它们创建一个包装器,比如说RawString并提供自定义Format[RawString],它也会在其writes方法中对字符串进行 HTML 转义。详情见:play.api.libs.json API 文档

于 2013-05-16T20:57:52.203 回答