I have developed a project that is quite big, I was thinking in improving security by saving a token in Session variable and sending that token in each form to check if it is correct to prevent from CSRF attacks.
The thing is that the project has many forms and it could be painful and take a lot of time to go through each form in order to add the token in a hidden input.
So I was asking myself, is there any easy way to add that hidden value to each form without having to go through each form?
Maybe using jquery, I could localize each form inside the page to add a hidden input, then add a general $_POST/$_GET function to check for any request if token is correct.
This is an idea, but probably there may be another simple and better way.
Is there any simple, fast and decent way to do so?
What would be the best approach in this situation (preparing CSRF attack prevention after project has been developed).
As far as I know the best way to prevent from CSR attacks is using token variables, is there maybe another decent way to do so without having to use a token and go through each form?
See here: Automatically insert CSRF token in all forms with JQuery.
You could add some code to a function, inline in a <script> tag as demonstrated:
jQuery(document).ready(function() {
jQuery("form").each(function() {
var tokenElement = jQuery(document.createElement('input'));
tokenElement.attr('type', 'hidden');
tokenElement.attr('name', 'token');
tokenElement.val(<?= $token ?>);
jQuery(this).append(tokenElement);
});
});
This will automatically add the server side $token to be included as a hidden form field for each <form> element.
If you want to achieve this without any server side processing, with the added benefit that all the above code could be included in a .js file, you could store the token in a cookie and simply access this value client side (using COOKIE plugin):
tokenElement.val($.cookie("csrftoken"));
Related
Suppose I maintain a anti CSRF token at server side in a session
How am I supposed to pass the token to client side application if my form generation is going to be dynamic(i.e. form will be created after some action has been performed by javascript)
Is there a way to pass the token to javascript so that I can inject the token in the form.
One working way that I found is send a cookie to the browser containing the token which will be then extracted by javascript.
Any suggestions?
I would suggest starting out from a secure token, and then improving it through JavaScript according to dynamic form Creation.
Eg, like:
<input type="hidden" name="csrftoken" value="hgdillksdbgjksdbkvbskb">
Where the "value" parameter is generated on server-side when page loads.
And then you have a script like:
csrftoken = document.mainform.csrftoken.value;
# Do something with the CSRF token, like add dynamic values, like sha256(csrftoken + "dynamicvalue");
document.mainform.csrftoken.value = csrftoken;
The main idea of this, is to prevent, that even if they manage to get a exploit that would allow a adverisary to read the JavaScript code, they still cannot make up a valid CSRF token, since they cannot read the original "csrftoken" value that was inside the form at page load.
This can also be used to "chain" AJAX requests, like that you start out with the token X during page load. Then you transform it to Y using JavaScript, send it in a AJAX request. In the next AJAX request, you can use Y as base in the algoritm, to create Z, and send to the server. A attacker cannot gain access to X, thus they cannot either get access to Y neither Z, even if they would in some way be able to exploit running JavaScript code to reveal itself.
Note that page contents cannot be read by a adversiary due to Same origin policy. But Javascript can contain exploits that would make it possible to read the actual running JavaScript code. Theres no such exploits currently, but better be safe than sorry.
Sure. If you're dynamically generating the form on the client side then you're doing it from some kind of template. The token should be an argument to that creation function.
Pass the token along to the client at request/render time and then inject it into the form as a hidden element at form generation time.
I have set up a rather complicated HTML form that uses the JQuery Validate plugin with several required fields and various rules. Form is working great. It POSTs to a separate PHP processor file that does a number of things such as send a couple of emails and eventually sends the user to Paypal. (It is a club membership application.) It appears that it only took about a week for some type of "bot" to find the processor file and start running it directly over and over. About 500 emails & apps were generated before I caught it and stopped it by renaming the files temporarily. At the time it was happening I wasn't quite sure exactly what was going on, but after evaluating it for most of the day I came to realize that it couldn't be as a result of the main form being executed, but by just running the processor file directly.
So...my question is this: How can I keep this from happening? There must be some type of coding to include that will ensure that the processor can't run unless it is really coming from the real HTML form...or is there a better way? I followed all of the "examples" on the 'Net in regards to forms and POSTing but nowhere did I see anything that relates to this type of problem.
Generally this can be reduced by adding a CSRF token to the form.
Set a random sha/md5 value to your session, and set that value in the form also as a hidden input, upon a legit user sending the form that value will be passed along too, validate and check the passed value with the one in session. if all is good process.
If its a bot, the bot would need to parse the form for the CSRF token first. Or you could step up and make that security key an image and make the user type it (captcha).
How to properly add CSRF token using PHP
Its something you should also add to your login forms ect, else your have bots brute forcing there way in.
Maybe you could add a $_SESSION[] global variable on the form page. Then check it on your processing page and unset it after execution. Sounds like the simplest way to me, but you should hear out what others suggest. You can fin documentation on $_SESSION[] variables here PHP $_SESSION
Add a token to the form when generating the page, and save it into the session.
When you got the post data, check the token with the one in the session.
And you probably want to use CAPTCHA code to protect yourself from the bots.
I wonder if I could put the crsf token in <head>, on a meta tag or something, and then access it on my server. It would really simplify the process and make it more transparent. I just don't know how. I was really hoping to do this without javascript involved.
I think rails implements something like that...with etags maybe?
There are many methods listed on the CSRF prevention cheat sheet. One that doesn't require a hidden field on every form, is to check the referer. Keep in mind the lack of the referer should be considered a CSRF attack and may cause problems with some privacy browser addons (which is very uncommon).
The fundamental purpose of a CSRF token is that it is delivered back to the server with each form submission. You deliver the unique token to a page, and when the form on that page is submitted the token comes back with it.
If you don't include the token on the form (or use JavaScript to programmatically add a token to the form that's currently elsewhere on the page) it will not be sent back to the server.
Perhaps the better question is: what is it you're really trying to accomplish? In other words, why would you not want to include a CSRF token within the form? What's the disadvantage you'd like to overcome in your scenario?
I've got a submission form, with 9 fields, 6 of which require validation, including a upload field with file size and file type validation.
Generating a random token, to prevent CSRF is working, but what is the correct way to validate when using a token?
If I do the validation within the same file, the token is regenerated with the validation reload. (can this be prevented? I've tried isset() but still regenerates.) However using the same file prevents the users Name and Email from being stored in a session.
Is it best to do the validation within a separate file, which then redirects back to the form with basic variables in the URL for each error, i.e. http://www.example.com/form?n=1
Using a separate file would also mean storing the form data within session, so the form can be repopulated if errors exist on the redirect.
Any help gratefully received.
From experience, CodeIgntier does great CSRF implementation, among other security mesures. I would suggest that you go over their code to gain a good understanding of the whole process. Also see this.
Question:
What is best practice for form submissions while keeping in mind security?
This may be a n00b question but I'm concerned that people might be able to alter some data as its being submitted. Take my example:
I have a form that has a hidden input that stores a user's unique Facebook ID. I take that Facebook ID and create a user account from it. If I use jQuery, won't some users be able to change the data being posted?
It is just as safe as a regular form post. Both methods can be hijacked and data injected. The key is how your server side scripts validate the data alongside authentication, session, anti forgery tokens etc
Users will always be able to post whatever data they like to your server. You can't do anything to change that with javascript. With a decent browser it's easy to find hidden form fields, unhide them, and put whatever you want in them. A more skilled user can craft an http post by hand and send whatever they like. Security must be done on the server, not on the client.