Chameleon模板是否为变量转义/删除XSS和HTML标记?以下是安全的吗?
<script type="text/javascript">
var initialComments = ${comments};
for (var i = 0; i < initialComments.length; i++) {
initialComments[i].userId = initialComments[i].user_id;
}
var post = ${post}
// ...
</script>
答案 0 :(得分:3)
这实际上比看起来更难,并且取决于具体情况。如果输出格式是HTML,则脚本内容是特殊的CDATA部分,其中不解释XML / SGML转义。如果输出格式是XML,具有XML内容类型,则转义按预期工作。尽管可以对变色龙进行修补,以便它将<script></script>
元素理解为特殊元素,但目前它并非如此。
当embedded in <script>
tag时,根据浏览器版本,单个</
或</script
将结束脚本标记,使其易受XSS攻击。此外,<
可以像<!--
一样启动HTML注释,遗留注意事项要求<script></script>
可以在脚本标记中平衡写入,因此最安全的是逃避{{1}在所有字符串中完全相同。
另一个问题是JSON is not a strict subset of JavaScript,如果你使用<
,允许字符串如U + 2028和U + 2029破坏脚本:
因此,在python / chameleon上执行此操作的正确方法是嵌入HTML中的ensure_ascii=False
标记:
<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')
我在Python bug跟踪器中发布了一个feature request来自动生成一个关键字参数,但它被拒绝了。
嵌入内容的更安全方法是将其存储在${structure: post_json}
属性中。
更新单独逃离data-*
是不够的。
答案 1 :(得分:1)
来自Chameleon introduction page:
默认情况下,字符串在插入前进行转义。要避免这种情况,请使用
structure
:前缀
但是,这不会逃避 JavaScript 值。使用JSON;在您的视图中,使用:
post_json = (json.dumps(post)
.replace(u'<', u'\\u003c')
.replace(u'>', u'\\u003e')
.replace(u'&', u'\\u0026')
.replace(u"'", u'\\u0027'))
生成 HTML-safe JSON字符串; JSON(由json.dumps()
至少 1 生成)是一个Javascript子集,这里有任何HTML危险字符转义(感谢Flask json.htmlsafe_dumps()
function)。
使用structure
:
<script type="text/javascript">
var initialComments = ${comments};
for (var i = 0; i < initialComments.length; i++) {
initialComments[i].userId = initialComments[i].user_id;
}
var post = ${structure:post_json};
// ...
</script>
1 JSON允许U+2028 and U+2029 characters,但json.dumps()
函数默认会转义所有非ASCII代码点。