如何让杰克逊逃脱输出字符串?

时间:2015-02-02 22:50:21

标签: javascript jsp jackson

我有一个简单的Java对象,我正在使用Jackson序列化为JSON,然后我将其放入JSP页面中的<script>标记中,作为初始化JavaScript对象的一部分。 e.g。

<script>SomeLib.load(${someObject});</script>

这非常有用,除非 someObject的某个字段是包含"</script>"的字符串,因为this issue。也就是说,如果输出如下所示:

<script>SomeLib.load({"someValue":"hacked!</script>"});</script>

然后浏览器(目前在Chrome和FF中均经过测试)认为</script>hacked!代码正在关闭脚本代码。这打破了JavaScript并使"});</script>对用户可见。

有没有办法让杰克逊以某种方式逃避这个价值来解决这个问题呢?

2 个答案:

答案 0 :(得分:3)

Ravis answer错了。在那里看我的评论。

更好的方法是使用反斜杠转义</中的斜杠,例如:

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<script>SomeLib.load(${fn:replace(jsonString, "</", "<\\/")});</script>

注意:需要两个反斜杠,以便在JSP语法中转义第一个反斜杠。

好的部分是,它不需要特殊的解码。

PS:要在杰克逊方面做,请参阅this blog - 它包括转义其他字符,但只需在列表中添加斜杠以转义(全部)斜杠字符。

答案 1 :(得分:0)

您可以使用JSTL函数fn:replace()仅使用<转义&lt;,这将有效防止JSON 字符串中的任何标记被解释作为HTML。

所以,这个

<script>SomeLib.load(${fn:replace(jsonString, "<", "&lt;")});</script>

将在浏览器中呈现为

<script>SomeLib.load({"someValue":"hacked!&lt;/script>"});</script>

但是,在使用replace()之前,您需要将JSTL 函数标记库导入为

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

  

不,这不会起作用,因为&lt;字面意思是在JavaScript字符串中(它没有转义)。

这就是重点,因为如果它以<形式出现,它将破坏HTML解析器/浏览器。

您需要记住,当协议或应用程序对某些内容进行编码时(如浏览器以UTF-8编码的URL字符串),在使用之前也需要对其进行解码(就像Web服务器使用URL时所做的那样)服务器端)或功能可能会中断。

因此,既然您知道您的JSON字符串是半编码的,那么您还需要修改消费者;将SomeLib.load()替换为&lt;的{​​{1}}方法,或者如果是第三方库,则在Javascript中解码其输入。

<