Regenerative Tokens
As maybe you already read the article new fashion, new ways (or not) article which presented a couple of methods on how to protect against CSRF, and which was though to be a good protection, especially the tokenized method (which is the preferred, and advised) though bulletproof… just thought, because recently while surfing blogs with blogsearch.google.com found out that the method I presented ain’t so fail proof as I though at first.
And as I don’t want people to complain that the code I provided won’t do what it’s supposed to do, I came up with a way to prevent CSRF from this new (actually not so new) method.
But first, for the ones that are too lazy to google for the answer, I would like to sum in a few words how the token method can be bypassed. Actually the concept is very simple (wonder why people haven’t though for it till now): get the page with the form (which contains the token) and build your custom form along with the grabbed token. Sounds simple, but how do we get the token? Through AJAX would say many, but that’s not the case because AJAX has a same site policy (can’t/will not grab requests from other websites). Intrigued by the method used for the request I found out (took me quite long 5-10min) that it could be done via dynamic script tag…
Back to our stuff… The way to protect against this CSRF protection bypassing is… is… yes you guessed it (damn title), by regenerating the token. But this has to be done via AJAX (try to make it without AJAX <- challenge)… Firstly our regeneration function… and an AJAX module php script (don’t know if it has a proper definition; you’ll understand later on)
—
//file name ajaxphp (for demonstrative reasons)
if($_GET["mod"]==”rtoken”) { regenerate_token(); }
//more functions can be added here
function regenerate_token() {
$nToken = rand();
if($_SESSION["token"]==$nToken) {
regenerate_token();
}
else {
$_SESSION["token"]=$nToken;
return md5($nToken);
}
}
—
And implementation in the page itself
—
<html>
<head>
…
<script>
function newtoken() {
//initialize xhr which is the AJAX object
xhr.open(”GET”,”ajaxphp.php?mod=rtoken”, true);
xhr.send();
//the onReadyStateChange stuff
document.myform.token.value=xhr.responseText;
}
</script>
</head>
<body onload=”newtoken()”>
…
<form name=”myform” action=”whatever.php” method=”post”>
<input type=”hidden” name=”token” value=”" />
…
</form>
</body>
</html>
—
And that’s it, we solved the problem… or at least I think (hope so), if not give me some feedback on other methods (if available) to bypass this method… Disadvantage from the previous (vulnerable method <- sort of) is that this one uses javascript code… but protection comes at a cost…
6 comments so far
Leave a reply











Thanks for this great article ;) I have a suggestion how to generate a new token without AJAX. Replys/Improvements are welcome.
token.html (just the important parts):
Getting a new token..
<!–
document.write(”");
//–>
newtoken.php:
document.getElementById(’newtoken’).innerHTML = ‘newtoken: some generated new token’;
Obviously my code snippets are not displayed correctly.
token.html -> http://rafb.net/p/6OxN2D46.html
newtoken.php -> http://rafb.net/p/pFG4AR74.html
sorry but the links seem broken, and I can’t see how you dynamically change the token in the session…
Next try ;)
token.html -> http://paste.bradleygill.com/index.php?paste_id=587
newtoken.php -> http://paste.bradleygill.com/index.php?paste_id=588
fyi: I’ve used dynamic script tag to do so ;)
[...] Regenrative Tokens (improvement of the CSRF protection) [...]
Спасибо вам большое за “толковый” рассказ, однако судите вы со своей колокольни и тупо не понимаете причин возникновения таких проблем.