Is it possible to degrade XSS attacks from browser?
I have a special case here, I don't use cookies for authentication, I send http token headers instead of that with javascript ajax. It is possible to protect those headers with closures:
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: "..."
});
This should work if $.ajax
and $.extend
both come from a secure source.
The username and password is still not protected, the DOM neither, etc... If I could load every external lib and my client side application from a single bootstrap closure without using the global namespace (attacker code usually injects javascript into the global namespace), it would be possible to protect everything on the server against xss. Without auth tokens the attacker code could not do anything on server side...
Of course I still sanitize everything on server side against xss, but in the case of an accidental xss vulnerability this would be an additional layer...
What do you think, does this worth the effort?
edit: Just for the sake of Benjamin:
<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>
Go on, steal the token your can override the injectedToken with anything except: stealing it with innerHTML of the SCRIPT node, and toString/toSource of the function itself, because normally the token come from the server, so it is not in this static format.
edit2:
I accepted the answer, because this is a hard way to protect your code against XSS. It is much easier to sanitize it well on server side.
conclusion:
With great care, you can protect small parts of your code with this method, for example in my case the auth token, but by larger code it is too much effort to protect every dependency. So this is just a complementary solution for very sensitive data, in the case it is necessary to store that on client side.