Page 1 of 1
CSRF attacks
Posted: Wed Jun 25, 2008 12:38 am
by alex.barylski
While digging through the bowels of DN looking for toipics on validation, filtering, etc I found an article by Maugrim which disccusess a request object using $_REQUEST instead of making the distinction between GET and POST.
I've read up on CSRF and ofund limited articles.
I have an application that users log into. The form is submitted via POST and voila they are allowed entrance into my application.
As I understand, if they were to click "Home" and google some malicious site, the site could force them into carrying out actions they otherwise wouldn't.
The malicious site would have them click a crafted link which would bring them back to my application and possibly delete a user account all through the user clicking on a link on the malicious web site. I assume having a FORM on a domain other than my own would raise errors in IE whereas the GET request would go unnoticed???
So a malicious site could use it's REFERRER code to detemrine the previous place visited, then craft a GET request which deleted user 123 and once they click on that link, BAM action taken, user deleted and now they might be in trouble.
Do I understand how this works correctly? Interesting attack, although it would not likely happen unless a disgruntled employee wanted to delete some accounts and sent his boss a link in MSN or something...
Anyways, my question...how do I prevent this from happening? What would I have to check in my Request object after I assigned $_REQUEST variable? Do I check the incoming domain is my own? Check the referer?
Cheers

Re: CSRF attacks
Posted: Wed Jun 25, 2008 1:02 am
by Stryks
I don't know if this really answers the question, but when I was first on here, someone pointed out that actions that modify data should always be requested with $_POST. Something like that anyhow.
So, I always use a form (using post method) when a delete or modify request is made, and this form always has a single use key in a hidden field - basically a random key is generated when the form is sent, stored in the users session and then embedded in the form.
When the form is submitted, I check to see if the key from the submitted form and the key from the session match, and if they do, the call goes through. Either way, the key is removed from the session - either deleted on success, or regenerated on form re-visit.
So, even if someone forged the parameters that would delete the form, and even if you were checking the $_REQUEST data and not the specific $_POST data, they wouldn't be able to forge a functional key and would therefore be boned.
I understand this also prevents other sites putting up forms that interact with your site. And when I was testing this a while back, no browsers threw any kind of error when posting to another domain. Perhaps this has changed in IE7??
You could possibly also check the referrer, but cant that information be modified by users? I don't know that I would trust it too heavily. Besides it really doesn't seem to add any additional protection to the scheme outlined above.
Re: CSRF attacks
Posted: Wed Jun 25, 2008 1:34 am
by alex.barylski
I'm pretty sure you can check the method (GET/POST/HEAD) so I think I will just check the method and the URI and determine if GET is allowed for a particular operation.
Problem is, I implement quick record deleting using GET, something like:
So that would still allow CSRF attacks, assuming the user was still logged in (ie: user didn't close browser).
Perhaps another way, would be to check referer and make sure it's from the same domain as the original FORM. Yes you can spoof the referer but these attacks will be coming from legitimate users, visiting maclisious sites, so unless they have some mod installed that allows them to spoof the referer I don't think that can happen.
That is, I dought you can influence the referer code from a GET request alone.
Re: CSRF attacks
Posted: Wed Jun 25, 2008 2:23 am
by Stryks
I think the one time pad could still work for you.
Even if you just have a random number generated on each page view and stored in the users session.
That way, an unauthorized attempt would need to send ...
Code: Select all
delete_user.php?pkid=2534&pad=235564335
The pad would change from page view to page view, and also be time limited by storing the timestemp on creation and comparing it to the time you attempt to process.
Even if going to a malicious site at that point allowed them to have logged in access to the delete_user.php file, they would have no access to the pad value that was in the form. Now even if they *did* get it, or guess it even, then they would have to do so in a timeframe that is defined by you.
Or am I solving a different issue here?

Re: CSRF attacks
Posted: Wed Jun 25, 2008 2:47 am
by CoderGoblin
I always find it interesting when people state $_GET is less secure that $_POST. The main reason to use $_POST as far as I am concerned is that it allows more data to be transfered. In reality it is relatively easy to hack a $_POST request if you actively want to do it. What you don't get is the casual user changing the $_GET value via the url. Ultimately it is always a case of Never trust user input.
Re: CSRF attacks
Posted: Wed Jun 25, 2008 2:51 am
by alex.barylski
I think were on the same page (it's really late here and my mind is fried so bear with me).
Your solution would work, however, it would be a royal PITA to retrofit my applicaiton with such a "fix". Every template would potentially need access to this PAD value.
If I can check the referer this can be done once and problem solved, that is, if I understand the threat properly.
1) User logs into my site
2) User receives MSN message from co-worker with link
3) User clicks on link and is redirected to malicious site
4) User see's a link they like and unknowingly click on malicious link
5) Malicious link looks something like below...
From
http://www.badsite.com
Code: Select all
http://www.mysite.com/admin/user_delete.php?243
Unless the user sees the link in the status bar and notices it's requesting a URL which is in the application domain, when they click the link, the action is carried out.
This is a basic attack, from what I understand of CSRF. You could potentially have a GET request on a malicious server possibly transfer funds from your bank account by having javascript send the POST data via GET to your bank account, assuming you were still logged in.
Same should go for POST now that I think about it...if you POST data from site A to site B the browser shouldn't care.
Someone could construct a special browsing agent which allowed them to spoof referer but anyone using a default browser would not have that desire.
I think the security implication comes in, because just clicking a link or posting a form on a malicious web site "could" send those requests to an existing session in a previously viewed web site/application (like a bank account, web application, etc).
Obviously, I'm not going to use FireFox and an HTTP spoofer plugin to send malicious GPC requests to my bank account (which is still logged in) and spoof the referer to get around any referer checks I might perform.
The only drawback I see to this approach, is that REST requests might fail, as they likely originate from a remote source, in which case a simple work around would be to spoof the referer in calling the REST server.
Bed time...need rest.

Re: CSRF attacks
Posted: Wed Jun 25, 2008 3:12 am
by Stryks
CoderGoblin, I'm not sure that anyone suggested that $_POST is more secure than $_GET, unless you're referring to my post where I stated ...
Stryks wrote:when I was first on here, someone pointed out that actions that modify data should always be requested with $_POST.
I've always been a bit baffled by it actually, but from memory it wasn't for security reasons, but more for standards compliance.
Actually, the post might have been on here. Yeah ...
HERE
Isn't that funny ... an offhand comment all that time ago has stayed with me and guided my thinking on my design processes. Weird.

Re: CSRF attacks
Posted: Wed Jun 25, 2008 3:25 am
by Mordred
You should read more on CSRF (and dare I say web technologies in general?), some things you say are simply wrong on the most basic level (Ah, I get it, just sleep a bit from time to time, will you

).
CSRF may happen:
- regardless of whether $_GET, $_POST, $_COOKIES or $_REQUEST was used.
- without the user having to click anything (javascript, it's what makes and breaks the web 2.0; also images, (i)frames, css)
- regardless of whether the user goes to the malicious site right after he was is the targeted site or not (it only suffices that he is logged in the target site)
- referer ([sic] ... one r, it's in the standard baby), while it would not be spoofed by the victim to his own demise, could simply be omitted. It's a simple privacy setting in every browser out there. Additionally (though I'm not familiar with the technique firsthand) I've heard that flash can be used to spoof HTTP headers, meaning that one should assume that the referer is faked anyway.
- the widely accepted method of protection is a per-form unique random token. It's called a
token, not a one-time pad (which is a totally unrelated crypto term)
- the token method may still fail if there is XSS on the site (the XSS-ed javascript can request the form asynchronously, parse the token and submit a valid request)
Re: CSRF attacks
Posted: Wed Jun 25, 2008 3:36 am
by Stryks
My bad calling it a pad .... I used to call it a token ... honest. Look at my old post.

Re: CSRF attacks
Posted: Wed Jun 25, 2008 12:20 pm
by alex.barylski
While security is a concern of mine, implementing this token technique would require to much retrofitting. I would have to add the hidden fields to all forms and I'm not even sure how I would deal with lists.
My First Record, Edit | Delete
My Second Record, Edit | Delete
My Third Record, Edit | Delete
In my list above, each action is constructed like:
I would need to retrofit each URL with this token. That would potentially introduce bugs, break the system and with over 300 templates I could easily miss one and still have a loop hole in my application.
Re: CSRF attacks
Posted: Wed Jun 25, 2008 12:55 pm
by Mordred
Well, I'm sorry to have to say that, but CSRF has been known for a long time, and it's entirely your fault that you haven't solved the problem at an earlier stage.
That said, CSRF is, in reality, only a problem for "potentially harmful" actions (it is up to you and the domain of the application to determine what that means). You only need to cover the cases where something is deleted, important data is changed, etc. No need to protect the search form, or the paging links, etc.
Re: CSRF attacks
Posted: Wed Jun 25, 2008 1:05 pm
by alex.barylski
Mordred wrote:Well, I'm sorry to have to say that, but CSRF has been known for a long time, and it's entirely your fault that you haven't solved the problem at an earlier stage.
Thanks for the vote of confidence. LOL
MVC has been around even longer and still most people don't "get it" does that make it their fault they misunderstand the importance of poor design? Or maybe, is it that no ONE person can understand everything there is to know about software development and this is why forums are so handy?
That said, CSRF is, in reality, only a problem for "potentially harmful" actions (it is up to you and the domain of the application to determine what that means). You only need to cover the cases where something is deleted, important data is changed, etc. No need to protect the search form, or the paging links, etc.
I'm going to have to sit down and come up with a simple, centralized prevention. Retrofitting all of my application with that token technique is unacceptable. It would take me weeks. For the time being I will just disable session storage in cookies and use URL's for propagation.
Nothing really mission critical, but people could have their records deleted, edited, etc...
Any ideas?
Re: CSRF attacks
Posted: Wed Jun 25, 2008 2:02 pm
by Bruno De Barros
[OFFTOPIC] Hockey...

Being afraid of breaking the application. You know, that's what Unit Testing is her for. Not attacking you, I myself only started using it one or two weeks ago. Imagine having all your code tested to the limit and everything, all just to see a small green bar saying "All tests passed" or whatever. If you decided to change the links, and make that "token" system, you could just reload the unit tests (like I do every hour of my work or when I change anything

), and then it would show you exactly what broke, what is out of place, and in 5-15 minutes, you would have the entire website fixed. It's amazing to go and make all the red bars disappear. Makes programming more like a game. Especially with Test Driven Development (make tests first of what you want to have, and then make the code to pass the tests). Whenever I have an idea for a class, I make several tests (examples, if you will), for different situations. This makes me think on how it will look like in the end BEFORE I start coding. I know from personal experience that after your code is done without unit tests you start sticking to the code you already know that works, and are afraid to change it or make new functions, or rename stuff. Then I get tons of red bars, and then I enjoy myself making all the bars disappear, until one green bar is left. It's tons of fun.
--
Anyway, if you don't want to change all the templates and all, and don't want to break anything, it's better to check the referer than not to check anything. Just my $0.02.
Re: CSRF attacks
Posted: Wed Jun 25, 2008 2:44 pm
by alex.barylski
Not attacking you, I myself only started using it one or two weeks ago. Imagine having all your code tested to the limit and everything, all just to see a small green bar saying "All tests passed" or whatever
Haha...no worries I'm not in any defensive position.
I did TDD and even gave BDD a whirl (as in write the test first, then implement). I prefer the latter although I am not 100% convinced of it's effectiveness in catching bugs (I would have to get back into for a few days before I could offer my arguments). I think I would prefer classical testing in terms of efficacy and BDD in terms of simplicity, but anyways.
I don't think unit testing would help here though, how would I write a test to ensure that each and every 300 templates had the token code in the required links or FORM posts? For starters, I wouldn't have those as tests as it doesn't make sense, testing a specific part of the interface that way.
Anyway, if you don't want to change all the templates and all, and don't want to break anything, it's better to check the referer than not to check anything. Just my $0.02
Like Mordred mentioned, the browser can be configured to disable sending that so it's unreliable -- although I imagine it's on by default.
I think I have figured out a clean solution and should only require a few lines of code and minutes to implement.
I need to spend some more time considering the consequences though before I implement it in my system.
Re: CSRF attacks
Posted: Thu Jun 26, 2008 7:08 am
by dbevfat
CoderGoblin wrote:I always find it interesting when people state $_GET is less secure that $_POST. The main reason to use $_POST as far as I am concerned is that it allows more data to be transfered. In reality it is relatively easy to hack a $_POST request if you actively want to do it. What you don't get is the casual user changing the $_GET value via the url. Ultimately it is always a case of Never trust user input.
GET is safer than POST, although minimally. When it comes down to forging the request, you can embed a GET request as a remote resource in a 3rd party website (via an image in a forum), while you can only POST if you can embed a form and submit it automatically (so you need to inject html and javascript in the same 3rd party forum website). There is no difference if you're hacking from your own website, where you can obviously display a hidden form and submit it automatically. Other than that, they're equally safe (=unsafe).
edit: typo