是否有可能降低浏览器的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攻击的难题。在服务器端清理它更容易。
结论
小心谨慎,您可以使用此方法保护代码的一小部分,例如在我的情况下使用身份验证令牌,但是通过更大的代码,保护每个依赖项都需要付出太多努力。因此,对于非常敏感的数据,这只是一个补充解决方案,如果有必要将其存储在客户端。
答案 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;
};
})();