在脚本标签中嵌入 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=&quot;foo&quot;: &quot;&lt;/script&gt;&quot;;</script> 

浏览器无法解释&lt;script&gt;标签。

我的问题是,

    在这种情况下我应该转义/不转义哪些字符? 是否有在 Python / django 中自动执行此操作的方法?

【问题讨论】:

只有在使用 XHTML 时,才能在 @yonran,所以,通过对 / 到 \/ 运行字符串替换来仅转义斜线就足够了吗? 是的,应该是这样。有关浏览器如何解析脚本标记的更多信息,请参阅 HTML 5 标记化: 对不起,我错了。让我澄清一下。 【参考方案1】:

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

但是您可能没有使用 XHTML。如果您使用常规 HTML,&lt;script&gt; 标记的行为有点像 XML 中的 CDATA 部分,只是它有更多的陷阱。它以&lt;/script&gt; 结尾。还有一些神秘的规则允许&lt;!-- document.write("&lt;script&gt;...&lt;/script&gt;") --&gt;(cmets 和&lt;script&gt; 开始标记必须同时存在,&lt;/script&gt; 才能通过)。在HTML 5 tokenization 和CDATA Escapes 中描述了 HTML5 编辑器为未来的浏览器采用的折衷方案

我认为要点是您必须防止 &lt;/script&gt; 出现在您的 JSON 中,并且为了安全起见,您还应该避免 &lt;script&gt;&lt;!----&gt; 以防止失控的 cmets 或脚本标签。我认为将&lt; 替换为\u003c--&gt; 替换为--\&gt; 是最简单的

【讨论】:

我要补充一点,您需要转义 HTML 字符 、& 和 = 以使您的 json 字符串可以安全嵌入。根据谷歌的 gson 库。 google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/…【参考方案2】:

我尝试用反斜杠转义正斜杠,这似乎有效:

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

你试过了吗?


顺便说一句,我很惊讶字符串中嵌入的&lt;/script&gt; 标记会破坏javascript。一开始不敢相信,但在 Chrome 和 Firefox 中进行了测试。

【讨论】:

embedded 破坏是意料之中的(我也认为这很奇怪),因为这意味着 js 解析必须沿着 HTML 解析完成(html 解析器必须知道 javascript 文本的语义),这对我来说似乎很复杂。 是的,HTML 解析器通常不会说 JavaScript。脚本标签的内容只有在 HTML 被解析后才会传递给解释器,并且 HTML 不会说标签在引号之间时不是标签! 是的,这是意料之中的——防止它的常用技巧是将标签分成两部分——"&lt;/scr" + "ipt&gt;"【参考方案3】:

我会这样做:

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

【讨论】:

【参考方案4】:

对于python中的这种情况,我在错误跟踪器中打开了bug。但是规则确实很复杂,因为&lt;!--&lt;script&gt; 即使在采用的 html5 解析规则中也以非常邪恶的方式一起玩。顺便说一句,“>”不是有效的 JSON 转义,因此最好将其替换为“\u003E”,因此绝对安全的转义应该是转义 \u003C 和 \u003E 以及 python 错误中提到的其他几个邪恶字符。 ..

【讨论】:

以上是关于在脚本标签中嵌入 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在 HTML 脚本标签中插入任意 JSON

有没有办法在 SVG 文件中嵌入 Google Web Font 脚本?

在 Python 中使用 BeautifulSoup 从 HTML 脚本标签中提取 JSON

原生js基础入门

原生js基础入门

如何使用美丽的汤从脚本标签中提取 json?