是否有可能从浏览器javascript降级xss?

时间:2013-11-20 06:52:00

标签: javascript xss

是否有可能降低浏览器的XSS攻击?

我在这里有一个特例,我不使用cookie进行身份验证,我发送http令牌头而不是使用javascript ajax。可以使用闭包保护这些标头:

var authModule = (function (ajax, extend){
    var authModule = {
        identified: false,
        login: function (identificationFactors){
            ajax("/session", {
                method: "POST",
                data: identificationFactors,
                success: function (data, status, xhr){
                    var token = xhr.getResponseHeader("auth-token");
                    authModule.onPermissionChange({
                        identified: true,
                        ajax: function (url, settings){
                            var settings = extend({}, settings);
                            settings.headers = extend({}, settings.headers);
                            settings.headers['X-Auth-Token'] = token;
                            return ajax(url, settings);
                        }
                    });
                }
            });
        },
        logout: function (){
            authModule.onPermissionChange({
                identified: false,
                ajax: ajax
            });
        },
        onPermissionChange: function (o){
            authModule.identified = o.identified;
            $.ajax = o.ajax;
        }
    };
    return authModule;
})($.ajax, $.extend);
authModule.login({
    email: "...",
    password: "..."
});

如果$.ajax$.extend都来自安全来源,这应该有用。

用户名和密码仍然没有受到保护,DOM也没有等等......如果我可以从单个引导程序关闭加载每个外部lib和我的客户端应用程序而不使用全局命名空间(攻击者代码通常会将javascript注入到全局命名空间),可以保护服务器上的所有内容免受xss的攻击。没有auth令牌,攻击者代码无法在服务器端执行任何操作......

当然我仍然在服务器端对xss清理所有内容,但在意外的xss漏洞的情况下,这将是一个额外的层......

您怎么看?这值得努力吗?

修改 只是为了本杰明:

<html>
<head>
<script>
var protectedDependency = (function (){
    var c = console;
    var log = console.log;
    return function (x){
        log.call(c, "protected: " + x); // <------- not secured dependency (Function.call) here, easy to forget...
    };
})();

var unprotectedDependency = function (x){
    console.log("unprotected: " + x);
};

var sandbox = (function (ajax, ajax2){
    return {
        sendToken: function (){
            ajax("my token");
            ajax2("some data");
        }
    };
})(protectedDependency, unprotectedDependency);
</script>
</head>
</body>
<script>
var injectedCode = function (){
    var log = console.log;
    var wrap = function (f){
        return function (x){
            log("stolen: " + x);
            f(x);
        };
    };
    console.log = wrap(console.log);
    protectedDependency = wrap(protectedDependency);
    unprotectedDependency = wrap(unprotectedDependency);
};
injectedCode();
sandbox.sendToken();
</script>
</body>
</html>

继续,窃取你可以覆盖injectToken的令牌,除了:使用SCRIPT节点的innerHTML和函数本身的toString / toSource窃取它,因为通常令牌来自服务器,所以它不在这种静态格式。

EDIT2:

我接受了答案,因为这是保护代码免受XSS攻击的难题。在服务器端清理它更容易。

结论

小心谨慎,您可以使用此方法保护代码的一小部分,例如在我的情况下使用身份验证令牌,但是通过更大的代码,保护每个依赖项都需要付出太多努力。因此,对于非常敏感的数据,这只是一个补充解决方案,如果有必要将其存储在客户端。

1 个答案:

答案 0 :(得分:2)

  • 如果一切都来自安全的来源,并且无法从远处运行脚本,那么无论如何你都可以安全地使用XSS。

  • 如果有人要运行脚本 - 那个关闭根本不会保护你。例如,人们可以在脚本中覆盖$.ajax,甚至可以覆盖XHR对象本身。闭包不会形成任何防止这种攻击的方式,也不应该这样做。 (另一方面WebWorker是可能的)。

一般来说 - 在你的情况下不值得努力。如果让任意脚本运行,你永远不会信任客户端。

为了好玩,因为我喜欢编码 - 这是一个简单的概念证明,可以在您的方案中窃取身份验证令牌。 Here is the result

(function externalCode() {
    var xhr = XMLHttpRequest;
    XMLHttpRequest = function () {
        var x = new xhr();
        setTimeout(function () {
            // for simplicity I assume it's done after 1 second
            console.log("Hijacked response", x.responseText);
        }, 1000);
        return x;
    };
})();