Can someone point me to information on how to protect applications from CSRF?
Any code related to this.
I am using extjs for the UI, Java on the backend and tomcat server.
Thanks in advance.
Use of the session id in the way the dan_waterworth suggests, while easy, is very poor protection. The attacker only needs to capture the session id cookie and then can circumvent the protection for the life of the session.
The session id is a cookie so it's submitted with any request. So all an attacker needs to do to capture the sessionid is to cause your application submit a request to a server under the attacker's control. This could be done by a cross-site scripting attack but can also be done by framing the app and submitting the iFrame's forms (there are other ways to do this).
The interaction that needs to be protected from CSRF should include information that the attacker cannot possibly know in advance (a CSRF Token) that is unique per session, per page and per form then ideally used only once. The CSRF token should be submitted in the form, and not in a cookie (for the reason mentioned above). See the 'implementation example' in the OWASP CSRF protection cheatsheet for details and a sample implementation. Some web application engines (e.g. Tomcat 8) and frameworks (e.g Spring, JSF) have protections that you can apply by turning on a configuration.
yes, I have a simple solution that has worked well for me. For each post request, send the sessionid in the data via javascript (obtained from the cookie) and on the server side it just needs to check that the sessionid cookie and the sessionid in the data are the same for every post request.
Related
I have a few questions regarding this:
In general, is XSRF still an issue with up-to-date browsers? To my knowledge cross-domain requests have been disabled by default and are now controlled through CORS. And when people are using outdated browsers, there are probably so many security holes in them that XSRF wouldn't matter anyways. BTW the XsrfTokenServlet class is still marked as not-for-production, so the GWT devs seem to consider it not an important issue or don't trust their own implemention.
Secondly, GWT uses a servlet to create the XSRF token. Doesn't that introduce an obvious attack vector by returning the (hashed) JSESSIONID? I thought you do XSRF exactly because the attacker doesn't know JSESSIONID and simply makes your browser send it along with the request. Now that request returns the critical hash of it that he can use to pretend he knows the JSESSIONID. What do I get wrong here? Shouldn't the JSESSIONID be hashed on the client side independently of the server to prove that the client actually can read the JSESSIONID cookie which isn't possible when calling the site from a page loaded from a different site?
Someone to explain please (hopefully with simple words for newbies) why a web application built upon a RESTful API can be CSRF exempt?
I received such assertion after asking: Serializing FormView data in JSON, but honnestly I can't figure out why?
Thanks in advance
CSRF or Cross Site Request Forgery, in layman terms, is meant to allow only selected sources(your own website) to submit data to particular url. It prevents misuse of your functionality by other websites or robots.
Say, I have an url for registration, /registration/, but I don't want to allow external submission of POST data to /registration/. So, I would provide a crsf cookie(depending on host and other stuff) when GET request is issued for /registration/, and ensure that same cookie is provided with POST request. This will ensure that users who have requested the registration form(i.e. genuine web users, not robots), would be able to register. It is not completely full-proof, but ensures some level of security.
Now, We don't use CSRF in API's due to following:-
Technically, CSRF is stored as cookie, since browser is not the intended client of API's, it is of no use.
Secondly, API's are supposed to use specialized client and user authentication, thereby eliminating the need for using any CSRF protection.
Thirdly, Restful api's are supposed to be stateless, therefore the order of API calls should not matter, which is essential for working of CSRF.
Note:-
If you have frontend framework like Angular or intend to use api's on browser too, then it is perfectly ok to use CSRF. In that case you are suppose to write two types of authentication for your apis.
Token Based Authentication - for non-browser clients
Session Authentication - for browser based clients (With csrf)
In this case, any request to api must authenticate with atleast one of the authentication.
According to owasp.org:
Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious Web site, email, blog, instant message, or program causes a user's Web browser to perform an unwanted action on a trusted site for which the user is currently authenticated.
This is not an issue for REST Web services because either:
1) you usually want your service to be accessible from multiple applications (Mobile app, browser, etc.)
2) you have to provide a direct authentication for each request, so this kind of attack is not applicable for REST services. The authentication is done by your application (let's say javascript) and no directly by your browser (sending the session id), so even if a malicious application redirect the user to your webpage, it cannot automatically trigger your javascript function to perform the request (and the authentication).
Is it a good practice to save the csrf token in a cookie or is it better to use a hidden field in a form? Also is it good to regenerate csrf token every user request like what captchas are doing?
Thanks
It is best to include it in the form. The idea behind a CSRF token is that it is not passed passively (e.g. if a malicious user is able to trick the browser into accessing some URL that does something nasty). Cookies are passed passively.
The best explaination to this question can be found on OWASP website at OWASP CSRF Prevention Cheat Sheet page.
Firstly, using cookie for a CSRF token can not help much because all cookies, even the secret ones, will be submitted with every request. All authentication tokens will be submitted regardless of whether or not the end-user was tricked into submitting the request.
Secondly, the application can include hidden input parameter in the form with a common name such as "CSRFToken". The value of this token must be randomly generated such that it cannot be guessed by an attacker.
Furthermore, Challenge-Response is another defense option for CSRF. It can be implemented in following ways:
CAPTCHA
Re-Authentication (password)
One-time Token
The CSRF cookie is certainly open to attack but implementation safe as the session value will always be checked against a submitted token value either stored in the body or header of the request so I can't see a reason against. The double submit (http only cookie vs post data) or token synchronizer (session vs post data) patterns outlined on the OWASP website are good pratices and both use cookies.
Double submit as mentioned earlier moves the storage to the client so is considered stateless but either way two tokens for comparison, of which one always remains unknown to the attacker.
I had one doubt about CSRF prevention. A lot of sites say that CSRF can be prevented by using 'tokens' which are randomly generated per session.
Now my doubt is,
suppose i have a function like :
$.post("abcd.php",{'fbuid':userid,'code':'<?php echo md5($_SESSION['randcode']); ?>'}
now this md5 hash would obviously be visible to any hacker through the source code.He could simply open this page, generate a token, and keep the page open, so that the session doesn't get destroyed, and useanother tab or anything else , to start hacking,
No ?
Or is my idea of tokens incorrect ?
Thanks for your help :D
I think you are misunderstanding what needs to be done. To protect against CSRF you need to create a token and save it for that session. Then you need to append all your submits and AJAX calls with that token.
For another person to send you to a page on your website they would need to have access to the request with in the same session. It is true that one could parse the HTML and look for the token. But when they try to request a http call on your website they will have a new session created. The new session will have a new token which will not match the token that was passed.
Next you will ask what if you can copy the cookies and the session id as a result. This is not something that is protected. I can simply sit anybody's computer and copy all their cookies and I will then be logged in as them.
As kapep points out, you are confusing the two seperate issues of input validation and cross-site form posting. You must validate your inputs anyway, so the case of your malicious attacker using his own session token is already handled if you have sound input validation. CSRF protection is not there to protect the data, it is simply to ensure that only forms from your own application can post data back to that application. the CSRF protection is simply stopping other people being able to post data directly into your app from forms they put up on their own site.
One specific point to be aware of is that the token is visible to any javascript running on your page, so as soon as you have a cross-site scripting (XSS) vulnerability, your CSRF protection is defeated.
See Cross-site scripting and the prevention cheat sheet
You should use a per request token.
Generate a token and store it in the session.
Pass the token to the client.
Execute actions.
Destroy the token.
The token is safer and cannot be used more than one time.
I would define a stolen token as a token that is used by someone else, and not the one you have send the token to. If you send someone a token he can't really steal it from himself.
If you are concerned that a user can run a malicious script with his own token, your design seems to be broken. You can't prevent a user from sending data that you didn't indented to receive. It's your job to validate any data, the session token is just there to identify multiple requests by the same client.
It could be a security issue if you send that token over unsecured http. Then it could easily be stolen by monitoring the clients network.
Am I correct, that if I pass a self-generated sessionID with every RPC request, and only check this sessionID instead of the one passed in the cookie header, the session can't be hijacked by malicious sites? I know that you should also send this sessionID in the cookie and then compare it with the one sent with every request to detect an XSRF attack but doing it my way should at least protect against XSRF attacks, doesn't it?
EDIT
I know that GWT 2.3 takes care of XSRF by providing XSRF Token Support. Sadly I'm stuck with GWT 2.2 and so have to deal with it by myself.
Yes, because the browser doesn't have enough information to convince your application that it has the right credentials. In a traditional XSRF attack the browser mechanism itself is being exploited and if it doesn't know how to send the extra information or what information to send then it just won't work.
However, with this approach, I would be aware that a malicious attacker could still compromise your self-generated sessionID and use it as soon as they figured out the mechanism.
See this wiki page on cryptographic nonce for more ideas. In using the nonce you're creating something that can only be used for that moment. Once the moment passes the data either becomes useless (in terms of a password salted with a time) or won't be accepted by the server. This is traditionally used to prevent replay attacks because, if you'll forgive me, the nonce has passed.
You might want to look at OWASP's CSRF Guard Project. They use a filter that checks every request to the server for the required CRSF Token. It's quite configurable - you can specify various aspects of your defense for ex:
URLs which don't require protection
entry point form which the CRSF Token
is to be generated (upon login)
the behaviour when a possible attack
is picked up (redirect, logging) etc
It's effectively a solution which requires no code change where the latest version also supports AJAX (RPC) calls to the server. So I believe it's definitely an option to try out (I'm currently POCing this solution for a fairly large GWT app).
Lastly I trust that you have already built your defenses against XSS. As XSRF defenses can be nullified if XSS is possible (not to mention that XSRF attacks are generally launched via XSS).