javascript - ColdFusion XSS Protection with 3 Contexts all-in-one

标签 javascript html security coldfusion xss

举个例子...

<cfset ascii32to126 = "!""##$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~">
<cfoutput>
    <input type="button" value="Submit" onclick="window.location='xss.cfm?demo1=#encodeForHtmlAttribute(ascii32to126)#'"><br>
    window.location='xss.cfm?demo1=!"##$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'<br>
    OBVIOUSLY THIS ONE IS INCORRECT
    <br><br>

    <input type="button" value="Submit" onclick="window.location='xss.cfm?demo1=#encodeForUrl(ascii32to126)#'"><br>
    window.location='xss.cfm?demo1=%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E%5F%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E'
    <br><br>

    <input type="button" value="Submit" onclick="window.location='xss.cfm?demo1=#encodeForHtmlAttribute(encodeForUrl(ascii32to126))#'"><br>
    window.location='xss.cfm?demo1=%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E%5F%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E'
    <br><br>

    <input type="button" value="Submit" onclick="window.location='xss.cfm?demo1=#encodeForHtmlAttribute(encodeForJavaScript(encodeForUrl(ascii32to126)))#'"><br>
    window.location='xss.cfm?demo1=\u002521\u002522\u002523\u002524\u002525\u002526\u002527\u002528\u002529\u00252A\u00252B\u00252C\u00252D\u00252E\u00252F0123456789\u00253A\u00253B\u00253C\u00253D\u00253E\u00253F\u002540ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00255B\u00255C\u00255D\u00255E\u00255F\u002560abcdefghijklmnopqrstuvwxyz\u00257B\u00257C\u00257D\u00257E'
</cfoutput>

我相信最后一个示例是针对 XSS 进行适当保护的那个,因为最终这会产生一个 URL(所以 encodeForUrl ),然后退后一步,您现在处于 JavaScript 上下文中(所以 encodeForJavaScript ),然后再进行另一个退后一步,您现在处于 HTML 属性上下文中(所以 encodeForHtmlAttribute )。我一直认为这就是过程,从代码最终将如何使用开始,然后倒退。 我理解正确吗?谢谢!

此外,从技术上讲,encodeForUrl() 的作用与 encodeForHtmlAttribute() 的作用相同,因此可以从最后一个按钮中删除 encodeForHtmlAttribute() 并且不会有任何改变,但我更愿意这样做,因为它有助于教学和理解。

最佳答案

是的,嵌套上下文是处理这个问题的正确方法。然而,最深编码的结果不太可能破坏周围的上下文,因为 ESAPI 函数尽可能严格并且转义符在这些上下文中不会重叠。因此,除非您需要处理不受信任的输入,否则无需嵌套编码。

encodeForHtmlAttribute( encodeForJavaScript( encodeForUrl(ascii32to126) ) )

例子:

encodeForURL("&")
>> %26

encodeForJavaScript("&")
>> \x26

encodeForHTML("&")
>> &amp; 

此处的所有控制字符对于其他上下文都是安全的。 % 在 JavaScript 和 HTML 中是安全的。 \ 在 URL 和 HTML 中是安全的。 &#; 在 URL 和 JavaScript 中是安全的。这并不一定意味着输出将被正确显示,但至少可以保证将其解释为文字字符串并且不会暴露任何安全风险。

结论:在我下面的示例中仅使用 encodeForUrl("1&b=2&c=3") 就足以抵御 XSS,因为编码输出是 JavaScript 和 HTML 中的文字字符串并且正确解码为 URL。


NOTE: My original answer was based on an outdated server setup of ColdFusion 10. Back then the input of the encodeFor functions were normalized/canonicalized and thus made nesting a security risk since only the last call was actually encoding the input.

不,嵌套编码会让你容易受到攻击(当且仅当每个 encodeFor 函数的输入都被规范化时,请参阅评论)。

考虑以下演示:

<cfset qs = encodeForHtmlAttribute( encodeForJavaScript( encodeForUrl("1&b=2&c=3") ) )>

<cfoutput>
    <button onclick="window.location='index.cfm?a=#qs#'">click me</button>
</cfoutput>
<cfdump var="#URL#">

这将导致 3 个单独的查询参数(abc),尽管您需要值 1&b= 2&c=3 在单个查询参数 a 中。原因是:规范化。编码器函数将在编码前对输入进行归一化,以防止双重编码攻击。

现在让我们尝试只对实际上下文编码一次:

<cfset qs = encodeForUrl("1&b=2&c=3")>

<cfoutput>
    <button onclick="window.location='index.cfm?a=#qs#'">click me</button>
</cfoutput>
<cfdump var="#URL#">

编码一次就足够了,因为转义字符在这些上下文中不会重叠。

关于javascript - ColdFusion XSS Protection with 3 Contexts all-in-one,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38753364/

相关文章:

javascript - PHP 和 AJAX 下载几 MB 文件卡住网站

Javascript/图像电子邮件混淆策略

javascript - SCSS根据id添加动画

javascript - 如何在静态博客网站上使用下拉菜单按年和月一起添加过滤器?

html - bootstrap col-xs 使内容不可见

javascript - 如何在jquery中进行纯客户端购物车计算?

javascript - Ember Shepherd 无法识别 DOM 更改

security - hadoop中用户级权限设置

java - 如何在 Java 中启用启用 SecurityManager 的情况下创建 newInstance

java - 角色、用户和权限管理工具