编辑:为了将来参考,我使用的是非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={"foo": "</script>"};</script>
,浏览器无法解释<script>
标记。
我在这里的问题是,
答案 0 :(得分:11)
如果您使用的是XHTML,则可以使用实体引用(<
,>
,&
)来转义<script>
中所需的任何字符串。您不想要使用<![CDATA[...]]>
部分,因为序列“]]>
”无法在CDATA部分中表达,您必须将脚本更改为表达]]>
。
但你可能没有使用XHTML。如果您使用常规HTML,<script>
标记的行为有点像XML中的CDATA部分,除了它有更多的陷阱。它以</script>
结尾。还有一些神秘的规则允许<!-- document.write("<script>...</script>") -->
(评论和<script>
开始标记必须同时存在才能传递</script>
。 HTML5编辑器为未来浏览器采用的折衷方案在HTML 5 tokenization和CDATA 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中提到的其他一些邪恶的角色...