金字塔变色龙模板安全的HTML和Javascript

时间:2014-04-09 11:05:04

标签: xss pyramid chameleon zpt

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>

2 个答案:

答案 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代码点。