这实际上比看起来更难,并且取决于具体情况。如果输出格式是 HTML,那么脚本内容是一个特殊的 CDATA 部分,其中不解释 XML/SGML 转义。如果输出格式是 XML,具有 XML 内容类型,则转义按预期工作。尽管可以修补 Chameleon 以使其将<script></script>
元素理解为特殊,但目前还没有。
当嵌入在<script>
tag中时,根据浏览器版本,唯一</
或</script
将结束脚本标记,使其容易受到 XSS 攻击。此外,a<
可以像 in 一样开始 HTML 注释<!--
,并且遗留的考虑要求<script></script>
可以在 script 标签内平衡写入,因此最安全的是<
在所有字符串中完全转义。
另一个问题是JSON 不是 JavaScript 的严格子集,如果您使用以下命令,则允许 U+2028 和 U+2029 等字符串破坏脚本ensure_ascii=False
:
因此,在 python/chameleon 上执行此操作,在 HTML 中嵌入<script>
标签的正确方法是使用:
post_json = (json.dumps(foo, ensure_ascii=False)
.replace('\u2028', r'\u2028')
.replace('\u2029', r'\u2029')
.replace('<', r'\u003c'))
这仅适用于嵌入在<script>
标签中的内容。
或者,如果您只想为几乎所有可以满足的字符获得不可读的转义:
post_json = json.dumps(foo, ensure_ascii=True)\
.replace('<', r'\u003c')
然后嵌入
${structure: post_json}
我在 Python 错误跟踪器中发布了一个功能请求,要求有一个关键字参数来自动执行此操作,但它被拒绝了。
嵌入内容的更安全方法是将其存储在data-*
属性中。
仅UPDATE转义</
是不够的。