在脚本标签中嵌入 JSON 对象
Posted
技术标签:
【中文标题】在脚本标签中嵌入 JSON 对象【英文标题】:Embedding JSON objects in script tags 【发布时间】:2011-05-09 18:10:14 【问题描述】:编辑:为了将来参考,我使用非 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>
标签。
我的问题是,
-
在这种情况下我应该转义/不转义哪些字符?
是否有在 Python / django 中自动执行此操作的方法?
【问题讨论】:
只有在使用 XHTML 时,才能在 @yonran,所以,通过对 / 到 \/ 运行字符串替换来仅转义斜线就足够了吗? 是的,应该是这样。有关浏览器如何解析脚本标记的更多信息,请参阅 HTML 5 标记化: 对不起,我错了。让我澄清一下。 【参考方案1】:如果您使用的是 XHTML,您将能够使用实体引用(&lt;
、&gt;
、&amp;
)来转义您想要在 <script>
中使用的任何字符串。您不想要使用<![CDATA[...]]>
部分,因为序列“]]>
”不能在 CDATA 部分中表达,您必须更改脚本以表达 ]]>
.
但是您可能没有使用 XHTML。如果您使用常规 HTML,<script>
标记的行为有点像 XML 中的 CDATA 部分,只是它有更多的陷阱。它以</script>
结尾。还有一些神秘的规则允许<!-- document.write("<script>...</script>") -->
(cmets 和<script>
开始标记必须同时存在,</script>
才能通过)。在HTML 5 tokenization 和CDATA Escapes 中描述了 HTML5 编辑器为未来的浏览器采用的折衷方案
我认为要点是您必须防止 </script>
出现在您的 JSON 中,并且为了安全起见,您还应该避免 <script>
、<!--
和 -->
以防止失控的 cmets 或脚本标签。我认为将<
替换为\u003c
和-->
替换为--\>
是最简单的
【讨论】:
我要补充一点,您需要转义 HTML 字符 、& 和 = 以使您的 json 字符串可以安全嵌入。根据谷歌的 gson 库。 google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/…【参考方案2】:我尝试用反斜杠转义正斜杠,这似乎有效:
<script type='text/javascript'>JSON="foo": "<\/script>";</script>
你试过了吗?
顺便说一句,我很惊讶字符串中嵌入的</script>
标记会破坏javascript。一开始不敢相信,但在 Chrome 和 Firefox 中进行了测试。
【讨论】:
embedded 破坏是意料之中的(我也认为这很奇怪),因为这意味着 js 解析必须沿着 HTML 解析完成(html 解析器必须知道 javascript 文本的语义),这对我来说似乎很复杂。 是的,HTML 解析器通常不会说 JavaScript。脚本标签的内容只有在 HTML 被解析后才会传递给解释器,并且 HTML 不会说标签在引号之间时不是标签! 是的,这是意料之中的——防止它的常用技巧是将标签分成两部分——"</scr" + "ipt>"
【参考方案3】:
我会这样做:
<script type='text/javascript'>JSON="foo": "</" + "script>";</script>
【讨论】:
【参考方案4】:对于python中的这种情况,我在错误跟踪器中打开了bug。但是规则确实很复杂,因为<!--
和<script>
即使在采用的 html5 解析规则中也以非常邪恶的方式一起玩。顺便说一句,“>”不是有效的 JSON 转义,因此最好将其替换为“\u003E”,因此绝对安全的转义应该是转义 \u003C 和 \u003E 以及 python 错误中提到的其他几个邪恶字符。 ..
【讨论】:
以上是关于在脚本标签中嵌入 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在 SVG 文件中嵌入 Google Web Font 脚本?