Is there a way to mitigate XSS attacks from browsers?
I have an interesting scenario where I do not rely on cookies for authentication. Instead, I use http token headers sent via JavaScript Ajax. It is possible to secure these headers using 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 approach should be effective if $.ajax
and $.extend
are sourced securely.
While the username and password remain unprotected, along with the DOM, etc., consolidating all external libraries and client-side applications into a single bootstrap closure without utilizing the global namespace could potentially shield everything server-side against XSS attacks. Without authentication tokens, malicious code injected by attackers would be rendered useless on the server side...
Naturally, thorough server-side sanitization against XSS vulnerabilities is still crucial, but implementing this additional layer could provide extra protection in case of accidental XSS exposure...
What is your opinion? Do you think it is worth the effort?
edit: Just for the sake of illustration:
<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>
Feel free to attempt to retrieve the token; you can override the injectedToken with anything except stealing it through innerHTML of the SCRIPT node or toString/toSource of the function itself, as the token typically comes dynamically from the server.
edit2:
I have marked the answer as accepted because this method provides a complex means of protecting your code from XSS attacks. However, it is much simpler and more effective to properly sanitize server-side validations.
conclusion:
With meticulous attention to detail, you can safeguard specific portions of your code using this technique, such as the auth token in my case. Nonetheless, protecting every dependency within larger codebases becomes overly burdensome. Hence, this solution serves best as a supplementary measure for securing highly sensitive data when storing it client-side.