If that is all that you're solving with that method, then the simple fact that you're using post not get as the form submission method (and you pull the variables from $_POST on the receiving page) is sufficient. The token doesn't gain you anything extra. As the malicious logic link uses a GET style query string....timvw wrote: This method does prevent CSRF. It requires that the user has visited my form page (to recieve a token)..
I don't care if he uses the data to generate a custom form, or a script that posts it (This is the nature of HTTP). All i care about is that he has a valid token..
External parties don't have this token, so they can't trick the user to post it...
Protecting your site from form tampering....
Moderator: General Moderators
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Well in the "Solution 2" method of generate and store a mapping table, you could just start your index at random(0,1000000). So the lookup table changes for every form, but because you've stored either the whole LUT in the session or just the starting offset you're safe.
In the case of "Solution 1" (HMACing), I'd probably take a generation approach and use cron to expire/rotate keys.
Your secret_config.inc has
Every N hours (4-8 is probably more than sufficient for most sites) rotate $current to $last and generate a new pair. (suitable use of MD5(getmypid,time, random, etc) is good enough for these.)
If the current key doesn't yield a match and you're within M minutes of the changeover, re-try using the last value. (Set M depending on how long an average user is to remain on the form without submitting it, probably capping at N/2).
In the case of "Solution 1" (HMACing), I'd probably take a generation approach and use cron to expire/rotate keys.
Your secret_config.inc has
Code: Select all
$current_hash_key=...;
$current_secret_key=...;
$last_hash_key=...;
$last_secret_key=...'If the current key doesn't yield a match and you're within M minutes of the changeover, re-try using the last value. (Set M depending on how long an average user is to remain on the form without submitting it, probably capping at N/2).
How about this:
Add a column to your users table `token`, then every page view you update it with sha1(uniqid()):
output $currenttoken to all forms, in every form have a hidden value "is_a_form" set it to 1. Then on any script that accepts form input, or even after the above code, on every page:
This would probably be sufficient for any of my php applications.
Add a column to your users table `token`, then every page view you update it with sha1(uniqid()):
Code: Select all
<?
$currenttoken=sha1(uniqid());
$oldtoken = mysql_query("SELECT `token` FROM `users` WHERE `user` = '$user' LIMIT 1");
// mysql_fetch_array and stuff
mysql_query("UPDATE `users` SET `token` = '$currenttoken' WHERE `user` = '$user' LIMIT 1 ; ");
?>Code: Select all
<?
if ($_POST['is_a_form']) {
if ($_POST['token']==$oldtoken) {
// Accept the form
} else {
// Form tampered
}
}
?>- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
I think I might be able to clear up some confusion.
CSRF is a category that includes all attacks where the attacker causes a victim to send arbitrary HTTP requests to a target site. Thus, the client sending the request is not the attacker, and this form of attack is especially effective when the victim has an established relationship with the target site. Most forms of access control, including those at the network layer, can be avoided with a CSRF attack.
Thus, by including a token in each form, you can effectively prevent CSRF. Yes, you can visit the form and view source, but this gains you nothing. You can already submit the form yourself legitimately - spoofing it only lets you avoid client-side restrictions. Knowing your own token does not help you forge a request from someone else - you would have to know their token.
Hope that helps.
I don't think you understand what CSRF is, so let me briefly explain. (If I'm mistaken, please accept my apologies. My opinion is based on your comments here.)nielsene wrote:It stops only the trivial CRSF exploit, but not a forged POST submission which is just as trivial. It does NOT test if they are coming from your page.
I could write a page on my website that POST'd to yours. I go to your site, view source, and add the token from your page to my page. Now your receiving script thinks my form is legitimate.
CSRF is a category that includes all attacks where the attacker causes a victim to send arbitrary HTTP requests to a target site. Thus, the client sending the request is not the attacker, and this form of attack is especially effective when the victim has an established relationship with the target site. Most forms of access control, including those at the network layer, can be avoided with a CSRF attack.
Thus, by including a token in each form, you can effectively prevent CSRF. Yes, you can visit the form and view source, but this gains you nothing. You can already submit the form yourself legitimately - spoofing it only lets you avoid client-side restrictions. Knowing your own token does not help you forge a request from someone else - you would have to know their token.
Hope that helps.
Yes, I'm not altogether clear on CSRF. I'm used to XSS (Cross Site Scripting), the two seem very similar to me.
The token method does not stop XSS, nor does it look like it stops CSRF. The malicious logic that the attacker's site causes the third-party client/victim to issue a dangerous request to the orginial server, can still acquire the clients token to use it its created request.
The token method does not stop XSS, nor does it look like it stops CSRF. The malicious logic that the attacker's site causes the third-party client/victim to issue a dangerous request to the orginial server, can still acquire the clients token to use it its created request.
Yeah, they're actually not very similar at all. Some people within the security community are trying to promote a new name - session riding. Their reason is to more clearly distinguish CSRF from XSS. I understand the motivation, but I personally feel that cross-site request forgery is much more accurate description of what is happening.nielsene wrote:Yes, I'm not altogether clear on CSRF. I'm used to XSS (Cross Site Scripting), the two seem very similar to me.
The token has nothing to do with XSS, so you're right about that.nielsene wrote:The token method does not stop XSS, nor does it look like it stops CSRF. The malicious logic that the attacker's site causes the third-party client/victim to issue a dangerous request to the orginial server, can still acquire the clients token to use it its created request.
For the other, try to think of a specific exploit that would allow you to obtain the victim's token. If you can think of an exploit that works, you should immediately share this, because using a token like this is currently considered the best practice to protect an application from CSRF. I think you'll be able to better appreciate the value in this approach as you try to develop an exploit. I'd be happy to help poke holes in anything you try, and I certainly hope there are holes, else we're all in big trouble. :-)