Hey Bill, thanks for sharing. I found your paper 2 days ago, but I’ve been on the road traveling and haven’t fully digested it. Same now with this plugin, but I will get to it, and I want you to know we take csrf very seriously. Thanks for sharing, and great to see you here.
If i understand it correctly CSRF depends on forms/requests using GET where a user has be logged in for. So if you don’t assign critical actions to GET requests you are safe?
No, the same methods can be use to hijack you session via POST under some conditions too. In fact, the very same techniques an be used to exploit unprotected XMLHttpRequest(AJAX) resources too.
Let me put it in another perspective, if you disable javascript your are safe as it is because of malware infected browsers that make these attacks possible, right? How else can an attacker add an image with an evil url to a trusted site’s html?
Ah i’m glad i came across this! I’ve been looking into using tokens in my forms to prevent this and was getting round to implementing it this week. I’ll be the first to admit that i’m too lazy to extend the helper, and was just going to do it per form.
The method that you’ve used is identical to what i had decided on doing after extensive reading. Now you’ve aided my utter laziness by doing it for me!
Thanks!
If there is a voting system for something that should be included in the CI core then this has got my vote with bells on.
@xwero,
It’s not infected browsers that make these attacks possible. It’s insecure sites.
If any site you visit has a xss vulnerability (and there are a lot of them), then someone can use that hole to forge a request to any other site. In this case you’re safe if javascript is turned off, yes.
But there are other ways to forge requests. Flash, for example, can make cross site requests (limited by crossdomain.xml, but i’ve seen large sites that just set it to * ). YouTube example. Here the attacker isn’t limited to GET.
Protecting yourself is important, but as a developer you can’t expect everyone who uses your site to have js turned off .
Out of Inparo’s information i understand the base of a CSRF attack is bad input control and the hacker has to have social hacking skills to attract people in using his malware.
EDIT:
THIS IS WORKING NOW…
(WORKING ON LOCALHOST AT THIS TIME.)
THE PROBLEM WHY IT WAS NOT WORKING: THE PARAMTERS FOR THE SETCOOKIE FUNCTION WERE NOT CORRECT. I CHANGED THE PARAMETERS AND NOW IT WORKS.
On line 90 of MY_Input.php
Changed from this:
setcookie(‘ci_token’, $ci_token, time()+$this->CSRF_expire, ‘/’, $domain);
TO THIS:
setcookie(‘ci_token’, $ci_token, time()+$this->CSRF_expire, “/”, “”, “0”);
BIll Zeller - 29 September 2008 11:13 PM
Hey guys,
...and also a plugin for Code Igniter (php 5 only) that can automatically protect against these type of attacks.
The CI plugin was written because Code Igniter is my framework of choice and I didn’t see a plugin available. I’ve love to hear your feedback.
Thanks!
Best Regards,
Bill Zeller
Thanks for the plugin…
I am having troubles getting it to work with Code Igniter 1.7
Any ideas or suggestions from anyone as to why it is not working?
I should specify the problem.
It is not setting the ci_token cookie.
It is getting down through the code and hits the setcookie()function, but the cookie is not setting.
Looking at code all day… probably just something simple, but I am not seeing the problem.
Any suggestions?
@Bill,
It’s not infected browsers that make these attacks possible. It’s insecure sites.
I don’t think that’s strictly true. The security flaw is attributable to the way browsers handle their security model that allows for a confused deputy exploit. When you log into a web site, you aren’t saying, “I want to have access to this web site,” you’re saying, “I want my browser to have access to this web site.” One of the design features of browsers is that they perform actions on behalf of their user, many times transparently (in the form of requesting images or sending AJAX requests). CSRF takes advantage of the browser’s implicit trust in itself to make good decisions about what actions it takes on its user’s behalf with its user’s permissions.
The most obvious way to solve the issue would be to unify site authentication models so a browser could reasonably determine if you have a secure session open for a particular domain. When a potential CSRF attack comes up (i.e. one domain is accessing a domain for which the user has an open secure session), the user can be prompted much like how popups are handled currently.
Unfortunately, that’s an “in the future” thing, and we have the problem now. It looks like this is a good solution, overall.
When you log into a web site, you aren’t saying, “I want to have access to this web site,” you’re saying, “I want my browser to have access to this web site.” One of the design features of browsers is that they perform actions on behalf of their user, many times transparently (in the form of requesting images or sending AJAX requests).
Unfortunately, the change in browser behavior you’re advocating would turn the browser experience into a Windows “Are you SURE you want to allow thread X access to process Y” Vista experience.
I *want* my browser to make micro-requests on my behalf, and not have to ask me about them. Popups are the exception because the vast majority of popups are unwanted, and most users can tell the difference. Most users wouldn’t know what to do with a cross-site security warning. Sometimes they’re fine, other times they’re not, and it takes a geek (or a computer) to tell them apart.
Think about the number of times that you have a secure session open on one domain and another domain requests a resource that’s specifically protected by that secure session (i.e. requesting the resource without the authentication token returns a 403/Forbidden header). This is a protection feature that would come up very rarely, and you could always design the dialogue to have an “Always allow” option.
Basically, such a behavior would create a conditional same-domain policy on protected resources.
Now you’re talking about authentication tokens - and tokens are a site implementation question. If the site doesn’t implement them, there’s little the browser can do about it - again, unless we’re talking SSL (which is already handled in the browser).
FIXED: the function getCSRFToken() is located outside of the class brackets in MY_Input.php and I “cleaned up” all the function brackets and missed where the class ended. My bad. —-
Bill, I’m getting this error from your CSRF code
Fatal error: Call to undefined function getCSRFToken() in W:\www\gfg\system\helpers\form_helper.php on line 64
I’ve autoloaded the CI input library, which should have accessed your MY_Input library, which is installed in system/applications/libraries and the MY_ prefix is set in the config file.
I’ve also loaded the ‘form_helper’ helper file, which is where the error points, but I have no idea why the function cannot be found.