I’ve been reading about CSRF and XSS vulnerabilities for a few days now, and trying to come up with a solution that’s 1) easy to implement and use, 2) uses Javascript to do a lot of heavy lifting, and 3) makes it virtually impossible to perform a CSRF attack against.
I haven’t seen a solution like the one I’m about to describe. I’m hoping this doesn’t mean that it’s leaky.
I’ve come up with the following solution, based on my knowledge of AJAX and JS. This code assumes the user has passed through a login screen, and a session variable has been set on the server and in a cookie, with the same values.
It’s easier to paste the code in and document it, rather than explain what it’s doing. This code would be run in the page the user sees immediately after logging in:
<script>
// this is the constructor:
function Controller(){
//the following 2 variables are private, and inaccessible via JS calls
var secretToken; //this holds the session token, but cannot be read by the browser
//returns the session token from the server
var x = new ajaxObject('AJAX/retrieve_session_cookie.lasso');
x.callback = function(responseText, responseStatus){
secretToken = responseText;
}
//this is a private function, again inaccessible via JS calls
function getCookie(){
x.update();
}
//the following 2 functions are publicly accessible
//just a test function to ensure that secretToken is invisible
this.tell = function(){
alert(secretToken);
}
//privileged function that calls a private function, to load the token into a private variable
this.initialize = function(){
getCookie();
}
}
E = new Controller();
E.initialize();
</script>
The variable secretToken can’t be read by the user, as it’s a private member variable of the controller object.
In retrieve_session_cookie.lasso, I’m checking for a valid session, and matching the session variable with the browser’s cookie. If both these conditions are met, the session variable is returned in plain text, where it’s set as secretToken in the object E. By double-checking to see if the cookie matches the session token, I would hope that it would be impossible obtain the session token via CSRF, as it can’t forge a cookie. Typing in ‘AJAX/retrieve_session_cookie.lasso’ would return nothing, unless it was typed in by the user while in a valid session, and from the user’s computer only.
Also, now that my controller has local access to the session token, I could ‘burn in’ the session token with every AJAX request, so I don’t even have to think about it passing a token anymore, each time an AJAX file is requested. All the AJAX objects and requests would be initialized as private members in the controller object’s constructor, so nobody could access / modify the callback functions to disclose the session token.
Passing the session token with every AJAX call would protect every other AJAX file, as they would all perform the same check for the cookie matching the session token before returning any data. And, in my programming, there would be one less variable to worry about.
If I were to move ahead with a controller implemented this way, would there be ANY way for the token to be accessed / exploited, either by the user or a malicious coder via CSRF?
First of all it is trivial for a user to obtain your token and for CSRF this doesn’t matter at all. Anything you transfer to the user can be intercepted, anything being sent from javascript can be tampered with. Cookies are always easy to replay (Who cares about forging them? Its just a random number.), and this doesn’t matter as long as you use HTTPS. To be honest I don’t think that this security system addresses CSRF at all, in fact I’m not sure what you are trying to protect against. It doesn’t matter where your
.lassofiles are or what they contain.What matters is the GET and POST requests can be forged. The whole point of having a CSRF token is that a 3rd party can’t create an exact GET/POST request without knowing somthing about the site(and a simple token written as a hidden value works because of Same-Origin Policy). Don’t roll your own security system, pick a solution off of the Cross-Site Request Forgery Cheat Sheet.