在脚本标记中嵌入JSON对象

时间:2010-11-14 06:52:52

标签: html django json

编辑:为了将来参考,我使用的是非xhtml内容类型定义<!html>

我正在使用Django创建一个网站,我正在尝试在我的页面中嵌入任意json数据以供客户端javascript代码使用。

假设我的json对象是{"foo": "</script>"}。如果我直接嵌入,

<script type='text/javascript'>JSON={"foo": "</script>"};</script>

第一个关闭json对象。 (另外,它会使站点容易受到XSS的攻击,因为这个json对象将被动态生成)。

如果我使用django的HTML转义函数,结果输出为:

<script type='text/javascript'>JSON={&quot;foo&quot;: &quot;&lt;/script&gt;&quot;};</script> 

,浏览器无法解释<script>标记。

我在这里的问题是,

  1. 在这种情况下,我认为哪些角色可以逃脱/不逃避?
  2. 是否有自动方式在Python / django中执行此操作?

4 个答案:

答案 0 :(得分:11)

如果您使用的是XHTML,则可以使用实体引用(&lt;&gt;&amp;)来转义<script>中所需的任何字符串。您想要使用<![CDATA[...]]>部分,因为序列“]]>”无法在CDATA部分中表达,您必须将脚本更改为表达]]>

但你可能没有使用XHTML。如果您使用常规HTML,<script>标记的行为有点像XML中的CDATA部分,除了它有更多的陷阱。它以</script>结尾。还有一些神秘的规则允许<!-- document.write("<script>...</script>") -->(评论和<script>开始标记必须同时存在才能传递</script>。 HTML5编辑器为未来浏览器采用的折衷方案在HTML 5 tokenizationCDATA Escapes

中有所描述

我认为必须要避免在JSON中发生</script>,为了安全起见,您还应该避免<script><!---->防止失控的评论或脚本标签。我认为最简单的方法是将<替换为\u003c,将-->替换为--\>

答案 1 :(得分:6)

我尝试使用反斜杠来逃避正斜杠,这似乎有效:

<script type='text/javascript'>JSON={"foo": "<\/script>"};</script>
你尝试过吗?


另外,我很惊讶字符串中的嵌入式</script>标记会破坏javascript。一开始无法相信它,但在Chrome和Firefox中进行了测试。

答案 2 :(得分:0)

我会做这样的事情:

<script type='text/javascript'>JSON={"foo": "</" + "script>"};</script>

答案 3 :(得分:0)

对于python中的这种情况,我在bug跟踪器中打开了bug。然而,规则确实很复杂,因为即使在采用的html5解析规则中,<!--<script>也以非常邪恶的方式一起玩。 BTW,“&gt;”不是一个有效的JSON转义,所以最好用“\ u003E”代替,因此绝对安全的转义应该是逃避\ u003C和\ u003E以及python bug中提到的其他一些邪恶的角色...