How to Implement Generic CSRF Tokens with JQuery AJAX? - php

I am currently developing jquery code that sends data to the server via ajax that is then inserted into the database based on the request parameters.
However, I am rather concerned that this could be abused by CSRF attacks which would make things rather insecure. I have tried to research this and only find answers for specific frameworks such as django and rails where I am only after a generic implementation for use with PHP.
I have read that you can use the JQuery.ajaxsend() function to implement the code so that a token is sent with EVERY AJAX request however I have no idea how this can be implemented as JavaScript obviously has no access to the PHP session variables. Would the use of cookies be secure enough?
Basically I need to be able to check the origin of the request to ensure that the request is genuine and not a forged request used to take advantage of the system.
If anyone can point me in the right direction that would be most appreciated!

Well, do know that $.ajax seems to send the cookies, including the PHP session cookie, with its request. Using that feature changes your attack from CSRF to session hijacking, but it's a start. Next, run your service over SSL if you can to avoid the session hijacking.
I'm sure there are other ways to do this as well, but for vanilla PHP, this seems to work. Someone correct me if I'm wrong, please.

Here's how it's done in Django, but there's nothing that's framework specific (besides setting the CSRF token in the cookie as 'csrftoken'): https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajax

Related

protect php script against csrf...without php session (cross site)

I have a public form that publish POST data to a PHP script.
This form is not located on the same domain, and doesn't use PHP either so the protection cannot be built around PHP session.
The goal is to allow only this form to post on that PHP script.
How do I provide more security for checking source of the request tells how to implement CSRF protection using PHP session but I wonder how I could do to protect mine without it? Is it possible?
POST requests are harder to fake compared to GET requests, so you have that going for you, which is nice. Just make sure you're not using $_REQUEST in your script.
You cannot use sessions here, but the principles are the same - you gotta implement some kind of a "handshake" between a form and your PHP script. There are a few different approaches if sessions are not an option.
The simplest thing to do would be to check http referrers. This will not work if the form is on http and script is under https, and also can be overcome using open redirect vulnerability.
Another way to go would be captchas. I know, not user friendly or fashionable these days, but that would make request forgery much harder, as hacker could not make his exploit work behind the scenes without any user input. You should look into reCAPTCHA (google's "I am not a robot" checkbox): https://www.google.com/recaptcha/intro/index.html
This is a tricky situation, because form on one host and script on another is basically CSRF in itself, so you want to allow it but only for one host. Complete security without any user interaction might be impossible here, so just try to make it as hard as possible for a would-be hacker to mess with your script, or suffer on the UX side. Personally i would go with reCAPTCHA.

Passing data from php session vertiable to ajax (with some jQuery in between)

I want to pass the user id and username stored in the session variable in php with an ajax request.
I know that i can print the values to the html of the page as a hidden text box, or as a jQuery data value, but i feel that this is not secure and that the user can make changes to the value and the ajax call will send that value which would make it in-secure. Please let me know how professionals handle this problem...
Thanks in advance!
Professionals handle this problem by carefully screening all input, enforcing strong password standards (so that users can't guess other users' passwords), and by storing the credentials in the code on the page but rather by using a randomly generated session token to map the user's token to identity on the server.
Client's can easily send any data they want by circumventing all of your client code. You have to assume the client is evil and look at protecting your server from that perspective.
EDIT:
If you need some help with tokens and their usage, this question might help you: PHP cookies and member security
If you are new to security I would highly recommend the Web Application Hacker's Handbook. I have read it and it is very thorough and interesting to read.
There is also a new book out called the Web Application Defender's Cookbook that looks quite promising, though I haven't read it.

Security questions about cookies and javascript

Ok, i have always wondered if these 2 actions are possible:
To manipulate cookies. I mean, if i login for example into facebook it will save a cookie in my browser. Could i edit it in anyway? I think so since it is set into MY browser and not set locally.
To manipulare a javascript script. I mean, since javascript is read by the browser and every user can read the language, could it be edited? For example, let's say i have an ajax call that send data strings like user=basic or something (it's just an example), could someone change it to user=admin?
I hope this kind of things are not possible or i am pretty much f****d!
In that case, I'm sorry to say you are pretty much f****d.
You must always assume that everything on the client side can be manipulated by some evil hacker. This includes cookies and JavaScript.
Firefox makes this extra easy, using the Edit Cookies extension for cookies, and Firebug to edit JavaScript (and HTML and CSS).
Both users and javascript can manipulate cookie data. However, broswers have optional (maybe default) protection against setting cookie data cross-domain.
I think modifying cookies should be pretty easy, as they're stored locally. I checked and in firefox there's a bunch of sqlite files that seem to have that. I don't know much about sqlite, but it seems that modifying them should not be a problem (especially since you could get to the browser source code in this case and see how it interacts with them :) )
I'm not sure about javascript modification, it most surely can be done by messing around with low level HTTP stuff (intercepting request and sending bogus responses with the modified code). Anti cross-site scripting policies helps a little, but I wouldn't rely on them much, there should be security checks server based to be safer.
Yes/No, your domain can only manipulate cookies set by your domain. Your JS script, being on youdomain.com or localhost cannot edit a cookie set by facebook.com. Think about it, Internet would have imploded by now if you could do that.
However, users can edit their cookies at will.
Yes.
Yes and yes, and there are even tools specifically designed to make doing so easy. Getting security right is hard, and unfortunately it's something that greener web developers often completely miss.
The only thing you can really safely store in a cookie is a login token. Basically, each time your user logs in, generate something like a GUID. Save the GUID to a column in the user's record (like LoginToken or whatever) and then set their cookie to the same GUID. When they logout, clear the record's LoginToken. Then when a request comes in, you can just query your database for the user who has a LoginToken equal to the value in the cookie. It's safe to assume that by holding the token, the requestor is in fact the user represented by the token.
If a malicious user edits their cookie, they'll get nothing more than logged out, since you'd treat a not-found token the same as no token at all.
On the server, once you check a token, you then determine if that user has admin rights (usually by looking at their record).
As far as being able to modify script, that's just a fact of life. Your server code has to assume that every request is malicious. Before you do anything, verify their token and verify that they're allowed to do what they're requesting.
2 things:
Validate the data client-side for usability, but also do it server-side to prevent someone from tampering with the data
Encrypt cookies to make it harder to manipulate

Is POST as secure as a Cookie?

While implementing a flash-based uploader, we were faced with an issue: Flash doesn't provide the correct cookies.
We need our PHP Session ID to be passed via a POST variable.
We have come up with and implemented a functional solution, checking for a POST PHPSESSID.
Is POSTing the Session ID as secure as sending it in a cookie?
Possible reason for: Because both are in the http header, and equally possible for a client to forge.
Possible reason against: Because it's easier to forge a POST variable than a Cookie.
It is as secure — forging the POST is equally as easy as the cookie. These are both done by simply setting flags in cURL.
That being said, I think you've got a good solution as well.
If you are able to obtain the session ID from active content in order to POST it, this presumably means that your session cookie is not marked HttpOnly, which one of our hosts claims is otherwise a good idea for defending against cross-site scripting attacks.
Consider instead a JavaScript-based or even refresh-based uploader monitor, which should integrate well enough with everything else that the cookie can be HttpOnly.
On the other hand, if your site does not accept third-party content, cross-site scripting attacks may not be of any concern; in that case, the POST is fine.
I think sending it via GET would also work fine, since you fake anything in a HTTP request (using curl or even flash).
The important thing is what is encrypted in you cookie/post/get parameter and how is it encrypted and checked on the server side.
Really if you are worried about which one is easier to forge, you're worrying about the wrong thing. Simply put, either will be trivial to an experienced attacker. You might keep out the "script kiddies" by choosing one over the other, but those people arern't the ones you need to be worried about. The question you should ask yourself is "what defenses do you have against someone forging an id?" It will happen. If your id is unencrypted, and easy to guess, that's a problem. It will get hacked. Since you are asking which is more secure, I would say that you are concerned.
Here's another thing to consider, since your application is flash, it's susceptable to modification (just like javascript HTML code), because the compiled code is on the attackers machine. They can look through the binary and figure out how the code works, and what it needs to retrieve from the server.
POST data is not an HTTP header, but it is sent as part of the TCP stream which makes it just as easy to read/forge as an HTTP header. If you intercepted an HTTP request it would look something like this:
POST /path/to/script HTTP/1.1
Host: yourdomain.com
User-Agent: Mozilla/99.9 (blahblahblah)
Cookie: __utma=whateverthisisacookievalue;phpsessid=somePHPsessionID
data=thisisthepostdata&otherdata=moredummydata&etc=blah
So as others have said, POST and cookies (and GET data, i.e. query strings) are all easy to spoof, since they're all just text in the same HTTP packet.
I just want to reiterate that both Cookie and Post are equally insecure.

Is encrypting AJAX calls for authentication possible with jQuery?

I'm fairly new to the AJAX methodologies (I only recently discovered jQuery a short time ago). I am interested to know if there is anyway to authenticate a user on a PHP setup; securely.
Does jQuery have any special options to allow use of HTTPS (or any other way to encrypt my ajax call)?
Yes, I could very well just post data back to the server, but that ruins the fun. :)
To use Ajax over HTTPS, you have to load the originating page over HTTPS.
Same origin policy
So, in a sense, yes -- but, not on its own.
Well, in case you are intrested. There is AES JavaScript implementation. I had lots of fun playing with it :). Still, it might be litte tricky...
Unless jQuery already does this (I use MooTools so I wouldn't know) I'd highly suggest that you link the AJAX login to the PHP session by using a $_GET variable in the query string. This way even though it's through HTTPS, you'll still know what session its tied to for an added layer of protection.

Categories