使用PlayFramework2在JSON中转义HTML

时间:2013-04-25 17:17:42

标签: java backbone.js playframework escaping playframework-2.0

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

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

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

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

第三个任务:
PlayFramework中是否存在手动转义字符串的函数?我能找到的所有内容都需要添加新的依赖项。

谢谢!

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

1 个答案:

答案 0 :(得分:3)

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

  • 除非您确切知道如何输出/渲染数据,否则撤销某些内容没有任何意义。因为不同的渲染方式需要不同的转义策略,例如,正确转义的HTML字符串不足以在Javascript块中使用它。需求和技术不断变化,今天你以一种方式呈现数据 - 明天你可能正在使用另一种方式(假设你将在一个不需要HTML转义的移动客户端上工作,因为它根本不使用HTML)渲染数据)在渲染数据时,您只能确定正确的转义策略。这就是现代框架委托逃避模板引擎的原因。我建议您查看以下文章:XSS (Cross Site Scripting) Prevention Cheat Sheet
  • 转义用户的输入实际上是一种破坏性/有损操作 - 如果您在将用户的输入保存到存储之前将其转义,您将永远不会知道他的原始输入是什么。对于'unescape'HTML转义字符串没有确定性的方法,请考虑上面的移动客户端示例。

这就是为什么我认为正确的方法是将转义委托给你的模板引擎(即你用于Backbone的Play和JS-templating引擎)。您不需要将序列化为JSON的HTML转义字符串。请注意,幕后JSON-serializer将JSON-escape你的字符串,例如如果你的字符串中有引号,它将被正确转义以确保生成的JSON是正确的,因为它是一个JSON序列化程序,这就是为什么它只关心正确的JSON呈现,它对HTML一无所知(它不应该)。但是,当您在客户端呈现JSON数据时,您应该使用您用于Backbone的JS-templating引擎提供的功能正确地对其进行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],这也将是HTML-escape writes方法中的字符串。有关详细信息,请参阅:play.api.libs.json API documentation