1

使用 OWASP 清单,保护这种情况的正确方法是什么?这是 javascript 字符串中的 url,其中 url 参数需要具有 xss 保护。

问题:

<script>
    var u = 'xyz.html?x=<% url.baddata %>'  
    dosomeAjax(u);
</script>

可能的解决方案1:

var u = 'xyz.html?x=<% encodeForURL(url.baddata) %>'

可能的解决方案2:

var u = 'xyz.html?x=<% encodeForJavaScript(url.baddata) %>'  

可能的解决方案3:

var u = 'xyz.html?x=<% encodeForJavaScript(encodeForURL(url.baddata)) %>'  
4

3 回答 3

3

应该使用解决方案 3:

//solution 3:
var u = 'xyz.html?x=<% encodeForJavaScript(encodeForURL(url.baddata)) %>';

如果我们将表达式重写为,则更容易看出这是正确的:

var u = '<% encodeForJavaScript("xyz.html?x=" + encodeForURL(url.baddata)) %>';

首先,我们通过baddata使用适当的转义函数附加到字符串常量来创建一个安全的 URL。然后我们把那个安全的 URL 放到一个 JavaScript 字符串中,所以我们必须调用 JavaScript 转义函数。

于 2012-05-08T02:28:16.740 回答
1

我要回答我自己的问题。在一遍又一遍地处理这种情况之后,解决方案非常明显,原因也很明显。

首先也是最重要的:插入到 javascript 中的任何字符串都需要是 javascript 安全的。无论如何,这总是需要发生:

<script>
  var x = "<% encodeForJavaScript(someCrazyString) %>";
</script>

这里的目标是确保此声明的安全。由于这是 javascript 代码,因此将其视为 javascript--这不是 url,因此 url 编码不正确。

现在,如果x要在 url 中使用它,则需要将其编码为 url。

唯一的事情是x现在是一个 javascript 字符串。所以服务器端编码是不可能的,因为字符串被推出了中间层,现在在浏览器中生存和呼吸。

解决方法是使用javascript的url编码功能: encodeURIComponentz()

<script>
  var x = "<% encodeForJavaScript(someCrazyString) %>";
  x = x + '234'
  var url = 'http://localhost/abc.cfm?x=' + encodeURIComponent(x)
</script>

从来没有理由使用 2 个服务器端 XXS 编码函数。始终使用单个服务器端编码函数并为上下文使用正确的服务器端函数:

网址:

<a href="xyz.jsp?x=<% encodeForURL(someString) %>" target="_blank" >click here</a>

js:

 <script>
   var x = "<% encodeForJavaScript(someCrazyString) %>";
 </script>

json:

 <script>
   var x = {"x"  : "<% encodeForJSONinJS(someCrazyString) %>"};
 </script>

更新(几年后)

执行 2 次服务器端编码将获得与一次在服务器端和一次在客户端进行编码相同的结果。所以解决方案 3 是正确的,当且仅当var u停留在 url 范围内。

进行 2 次服务器端编码的危险在于,您只能在第一次编码 的上下文中使用该片段。

以上面的示例为例,再添加 1 行:

 <script>
     var u = 'xyz.html?x=<% encodeForJavaScript(encodeForURL(url.baddata)) %>
     dosomeAjax(u);
     document.getElementById('someDivTag').innerHTML= u;
 </script>

现在有问题,因为 u 是 url 编码的而不是 html 编码的。(在这种特殊情况下,这不会出现 xss 可变性,因为您无法将 url 编码的字符串分解到 js 范围内——尽管如此,还有许多其他情况需要对字符串进行 2x 编码)。

为了灵活性,我的偏好是在服务器上编码一次,并根据客户端的需要编码为:

 <script>
     var x = "<% encodeForJavaScript(someCrazyString) %>";
     var u = 'http://localhost/abc.cfm?x=' + encodeURIComponent(x)
     dosomeAjax(u);
     document.getElementById('someDivTag').innerHTML= u.toHtml();
 </script>

哪里toHtml()是:

    var __entityMap = {
            "&": "&amp;",
            "<": "&lt;",
            ">": "&gt;",
            '"': '&quot;',
            "'": '&#39;',
            "/": '&#x2F;'
    };

    String.prototype.toHtml = function() {
            return String(this).replace(/[&<>"'\/]/g, function (s) {  
                    return __entityMap[s];
            });
    }

我正在检查 Cheran Shunmugavel 的答案是否正确。

于 2014-05-01T01:13:22.690 回答
0
var u = 'xyz.html?x=<% encodeForURL(encodeForJavaScript(url.baddata)) %>' 

EncodeForURL 应该放在最后。

<插入强制性“评估不好,你在想什么??”>

于 2012-05-07T21:13:39.410 回答