是否有可能降低来自浏览器的 XSS 攻击?
我这里有一个特例,我不使用 cookie 进行身份验证,我发送 http token header 而不是使用 javascript ajax。可以使用闭包保护这些 header :
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 也没有,等等......如果我可以从一个引导闭包加载每个外部库和我的客户端应用程序而不使用全局命名空间(攻击者代码通常将 javascript 注入(inject)到全局命名空间),可以保护服务器上的所有内容免受 xss 攻击。没有身份验证 token ,攻击者代码无法在服务器端执行任何操作...
当然,我仍然针对 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>
继续,窃取 token 你可以用任何东西覆盖 injectedToken 除了:用 SCRIPT 节点的 innerHTML 和函数本身的 toString/toSource 窃取它,因为通常 token 来自服务器,所以它不在这种静态格式。
编辑2:
我接受了这个答案,因为这是一种很难保护您的代码免受 XSS 攻击的方法。在服务器端对其进行良好清理要容易得多。
结论:
非常小心,您可以使用此方法保护代码的一小部分,例如在我的例子中是 auth token ,但是对于较大的代码,保护每个依赖项需要付出太多努力。因此,这只是针对非常敏感数据的补充解决方案,以防需要将其存储在客户端。
最佳答案
如果所有内容都来自安全源并且无法从远处运行脚本,那么无论如何您都可以免受 XSS 攻击。
如果有人开始运行脚本 - 关闭将根本无法保护您。例如,人们可以在他们的脚本甚至 XHR 对象本身中覆盖
$.ajax
。闭包不会形成任何保护免受此类攻击的方式,也不应该形成这种方式。 (另一方面,WebWorker
是可能的)。
通常 - 在您的情况下不值得付出努力。如果让任意脚本运行,您将永远无法信任客户端。
为了好玩,也因为我喜欢编码 - 这是一个简单的概念证明,它可以在您的方案中窃取身份验证 token 。 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;
};
})();
关于javascript - 是否可以从浏览器 javascript 降级 xss?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20089301/