CSRF protection only for requests with side effect (POST, DELETE, PUT)? - security

As far I understand Cross-Site Request Forgery attacks they "only" used to change state on Server side.
Assume:
I have a REST Web Application, and I am sure that HTTP GET requests does not change my application persistent state (no side effects)
I use a session-specific key to authorize the requests
Do I need to verify the session-specific key for GET Request?

It's not really a question of the request method (GET and POST can both make changes to persistent state), as each can be exploited by various CSRF attack vectors. When you talk about a "session-specific key", I assume you're talking about a synchroniser token pattern (more on this in OWASP Top 10 for .NET developers part 5: Cross-Site Request Forgery (CSRF)). Obviously this is intended to protect against the browser making unauthorised requests on your behalf under the orchestration of a third party.
So the question is really "Does my app require protection against CSRF?" It sounds like there's no change to persistent data in your app anyway so on the surface of it, the answer is "no". You generally only find anti-request forgery tokens in places where a CSRF attack would have an adverse impact so it sounds to me like it's something you don't need to worry about.

Related

What is the place the JSONP in CORS platform?

I m researching CORS Attacks, XSS and JSONP and Cross Origin Embedding models to getting informations about cross origin resource sharing. But I dont understand clearly JSONP logic. I m new for this topic. Any person can use JSONP for attacks? And how can we prevent from this kind of attacks? And also could you explain CSRF token ?
JSONP is a bit dodgy, from a security perspective:
Requires excessive trust. Suppose you have a page hosted on a.com and it uses JSONP to access services provided by b.org. This involves placing 100% trust in b.org. If b.org is malicious or buggy, it can subvert the security of the embedding page and all of the a.com origin. This kind of excess trust is dangerous from a security perspective: it makes your application fragile.
To put it another way: JSONP is basically a self-inflicted XSS. Yes, OK, I know it's a feature, not a bug, but still...
CSRF vulnerabilities. You have to remember to defend against CSRF vulnerabilities, and with JSONP, that gets a bit tricky. Standard advice is to ensure that only POST requests can trigger a side-effect, and to include a CSRF token in all POST requests; but JSONP involves sending a GET request to trigger a side-effect, which ain't exactly the cleanest solution you've ever seen. So this means that the host that provides JSONP service needs to remember to check CSRF tokens even on GET requests. Also, it requires a bit of a tricky protocol for the embedding page (a.com) to obtain the proper CSRF token from the JSONP service (b.org). It gets messy.
Causes mixed-content warnings. Suppose we have a page hosted on https://a.com and it accesses a JSONP service on http://b.org. Then this will inevitably trigger a scary-looking mixed-content warning (since JSONP involving loading a script from http://b.org).
User authentication gets ugly. If b.org wants to authenticate the user, that gets tricky to do when using JSONP. The embedding page (a.com) needs to first somehow give the user an opportunity to log into b.org in advance, before accessing b.org's JSONP service. Both sites need to coordinate.
Here's a summary of the security issues with JSONP, as I understand it:
From the consumer's perspective:
You must trust the provider to not return malicious JavaScript instead of the expected JSON wrapped in the JSONP callback you specify.
The same is also true of any third party JavaScript embedded add-ons, such as Google Analytics.
It's only similar to XSS attacks in that it allows a 3rd party to execute arbitrary JavaScript in your application, however, you must first choose to trust that 3rd party by making the request in the first place.
From the provider's perspective:
You must not assume that even though the clients' cookie(s) are present in the request that the consumer is a webpage under your control. Check the Referer header against a whitelist of authorized URLs, and/or don't rely on cookie-based authentication.
Analogous to a CSRF / confused deputy attack.

Why not include CSRF protection for GET apis?

I was reading up on CSRF and came across this question: https://security.stackexchange.com/questions/36671/csrf-token-in-get-request
Multiple people online have also seem to indicate that one should not protect GET requests against CSRF. However, I am confused by why.
If your GET request contains sensitive information (like say personal info for a user), then you would want to protect it against CSRF right? Otherwise an attacker can steal personal info.
I get that you shouldn't include the token in the GET URL because those may be logged. However, can't you just include them in a custom header?
CRSF attacks are blind. They typically send a request without being able to read the result of the action. The reason here is the Same Origin Policy.
SOP prevents you from reading RESPONSES received by other origins, meaning that you can't access the private stuff anyways.
CRSF protection instead protects REQUESTS in the sense that it adds a token which symbolizes that the request is started by the web app itself

Securing oauth bearer token against attacks such as XSS, CSRF in javascript apps

I am a bit unclear about how to secure (or protect) bearer tokens when using pure JavaScript applications.
I know when user request token to the server it can come with a validity of 14 days or 24 hours. but once the user has token there is no neat (assured) way of securing this from XSS or CSRF attacks (am I missing something?).
Now lets say user is logged into the web application and the browser has this token which is valid for 14 days. If the user is accessing another web application which is trying to do XSS (or CSRF) then the token is exposed to the third party application and this application can make calls to the my application using this token (?)
I have tried to search online but nothing concrete (or something which is easy to understand) coming up for pure js apps and how to protect the token. Or there isn't a good way to do it in js atm. and you just hope (and pray) that the attack will not take place within the validity of token (i.e. 14 days :|)?
Any thoughts or inputs are welcome to this.
Thanks
Edit: It prob. goes without saying but we are assuming the use of SSL certificate.
So, a very quick summary. CSRF occurs because a request to a HTTP end point automatically includes cookies (as it should) plus required headers as described by the server and doesn't require a user to physically do something. They simply visit a web page with the CSRF vector on.
CSRF is generally said to be possible if there is no use of a unique "secret" passed firstly to the client and back to the server to verify that the user indeed intended to make the call. Generally speaking, web browsers are shaping the main ways to protect against CSRF for any type of application. CSRF on OWASP
As you've pointed out, you use a bearer token (sent as a HTTP header) - but you are still protected because requests need to originate from the same origin by default. IF the server allows calls from all origins which is returned in the HTTP headers (which tells your user's web browser if it is allowed) then on their heads be it Same origin policy here.
As for XSS, as long as your cookies at the very least have the "HTTP" flag they are invisible to javascript code on any page the user visits anyway. Plus strictly speaking XSS vectors including the theft of cookies for your site would need to be performed on your site generally speaking. Off the top of my head I can't think of anyway to steal them unless a user is physically on your site. If you set the "Secure" flag this is even better as it forces "Server" only too and ensures the cookie will only be sent when a TLS/SSL connection has been established. XSS on OWASP
Here is a screenshot of cookies listed with the Secure and HTTP flags:
As an extra, make sure you always enforce TLS connections as otherwise they could become victim to a MITM (Man in the middle) attack on a public WIFI network that forces a protocol downgrade to a weak version of SSL that is susceptible to POODLE or non at all. Please read up on HSTS as it will most definitely reinforce everything I have mentioned and really help to prevent the token from being stolen HSTS OWASP and HSTS info wikipedia

Is CSRF possible with PUT or DELETE methods?

Is CSRF possible with PUT or DELETE methods? Or does the use of PUT or DELETE prevent CSRF?
Great question!
In a perfect world, I can't think of a way to perform a CSRF attack.
You cannot make PUT or DELETE requests using HTML forms.
Images, Script tags, CSS Links etc all send GET requests to the server.
XmlHttpRequest and browser plugins such as Flash/Silverlight/Applets will block cross-domain requests.
So, in general, it shouldn't be possible to make a CSRF attack to a resource that supports PUT/DELETE verbs.
That said, the world isn't perfect. There may be several ways in which such an attack can be made possible :
Web Frameworks such as Rails have support for "pseudo method". If you put a hidden field called _method, set its value to PUT or DELETE, and then submit a GET or POST request, it will override the HTTP Verb. This is a way to support PUT or DELETE from browser forms. If you are using such a framework, you will have to protect yourself from CSRF using standard techniques
You may accidentally setup a lax response headers for CORS on your server. This would allow arbitrary websites to make PUT and DELETE requests.
At some point, HTML5 had planned to include support for PUT and DELETE in HTML Forms. But later, they removed that support. There is no guarantee that it won't be added later. Some browsers may actually have support for these verbs, and that can work against you.
There may just be a bug in some browser plugin that could allow the attacker to make PUT/DELETE requests.
In short, I would recommend protecting your resources even if they only support PUT and DELETE methods.
Yes, CSRF is possible with the PUT and DELETE methods, but only with CORS enabled with an unrestrictive policy.
I disagree with Sripathi Krishnan's answer:
XmlHttpRequest and browser plugins such as Flash/Silverlight/Applets
will block cross-domain requests
Nothing stops the browser from making a cross-domain request. The Same Origin Policy does not prevent a request from being made - all it does is prevent the request from being read by the browser.
If the server is not opting into CORS, this will cause a preflight request to be made. This is the mechanism that will prevent a PUT or DELETE from being used, because it is not a simple request (the method needs to be HEAD, GET or POST). Assuming a properly locked down CORS policy of course (or none at all which is secure by default).
No. Relying on an HTTP verb is not a way to prevent a CSRF attack. It's all in how your site is created. You can use PUTs as POSTs and DELETEs as GETs - it doesn't really matter.
To prevent CSRF, take some of the steps outlined here:
Web sites have various CSRF countermeasures available:
Requiring a secret, user-specific token in all form submissions and side-effect URLs prevents CSRF; the attacker's site cannot put the
right token in its submissions1
Requiring the client to provide authentication data in the same HTTP Request used to perform any operation with security
implications (money transfer, etc.)
Limiting the lifetime of session cookies Checking the HTTP Referer header or(and)
Checking the HTTP Origin header[16]
Ensuring that there is no clientaccesspolicy.xml file granting unintended access to Silverlight controls[17]
Ensuring that there is no crossdomain.xml file granting unintended access to Flash movies[18]
Verifying that the request's header contains a X-Requested-With. Used by Ruby on Rails (before v2.0) and Django (before v1.2.5).
This protection has been proven unsecure[19] under a combination of
browser plugins and redirects which can allow an attacker to
provide custom HTTP headers on a request to any website, hence
allow a forged request.
In theory it should not be possible as there is no way to initiate a cross-domain PUT or DELETE request (except for CORS, but that needs a preflight request and thus the target site's cooperation). In practice I would not rely on that - many systems have been bitten by e.g. assuming that a CSRF file upload attack was not possible (it should not be, but certain browser bugs made it possible).
CSRF is indeed possible with PUT and DELETE depending on the configuration of your server.
The easiest way to think about CSRF is to think of having two tabs open in your browser, one open to your application with your user authenticated, and the other tab open to a malicious website.
If the malicious website makes a javascript request to your application, the browser will send the standard cookies with the request, thus allowing the malicious website to 'forge' the request using the already authenticated session. That website can do any type of request that it wants to, including GET, PUT, POST, DELETE, etc.
The standard way to defend against CSFR is to send something along with the request that the malicious website cannot know. This can be as simple as the contents of one of the cookies. While the request from the malicious site will have the cookies sent with it, it cannot actually access the cookies because it is being served by a different domain and browser security prevents it from accessing the cookies for another domain.
Call the cookie content a 'token'. You can send the token along with requests, and on the server, make sure the 'token' has been correctly provided before proceeding with the request.
The next question is how do you send that value with all the different requests, with DELETE specifically difficult since it is not designed to have any kind of payload. In my opinion, the cleanest way is to specify a request header with the token. Something like this x-security-token = token. That way, you can look at the headers of incoming requests, and reject any that are missing the token.
In the past, standard ajax security restricted what could be done via ajax on the malicious server, however, now-a-days, the vulnerability depends on how you have your server set up with regards to accees-control configurations. Some people open up their server to make it easier to make cross domain calls or for users to make their own RESTful clients or the like, but that also makes it easier for a malicious site to take advantage unless CSRF prevention methods like the ones above are put in place.

Is this CSRF Countermeasure Effective?

Please let me know if the following approach to protecting against CSRF is effective.
Generate token and save on server
Send token to client via cookie
Javascript on client reads cookie and adds token to form before POSTing
Server compares token in form to saved token.
Can anyone see any vulnerabilities with sending the token via a cookie and reading it with JavaScript instead of putting it in the HTML?
The synchroniser token pattern relies on comparing random data known on the client with that posted in the form. Whilst you'd normally get the latter from a hidden form populated with the token at page render time, I can't see any obvious attack vectors by using JavaScript to populate it. The attacking site would need to be able to read the cookie to reconstruct the post request which it obviously can't do due to cross-domain cookie limitations.
You might find OWASP Top 10 for .NET developers part 5: Cross-Site Request Forgery (CSRF) useful (lot's of general CSRF info), particularly the section on cross-origin resource sharing.
If a persons traffic is being monitored the hacker will likely get the token also. But it sounds like a great plan. I would try to add a honeypot. Try to disguise the token as something else so It's not obvious. If it's triggered, send the bad user into the honeypot so they don't know they've been had.
My philosophy with security is simple and best illustrated with a story.
Two men are walking through the woods. They see a bear, freak out and start running. As the bear catches up to them and gaining one of them tells the other, "we'll never outrun this bear". the other guy responses, "I don't have to outrun the bear, I only have to outrun you!"
Anything you can add to your site to make it more secure the better off you'll be. Use a framework, validate all inputs (including all those in any public method) and you should be ok.
If your storing sensitive data I would setup a second sql server with no internet access. Have your back-end server constantly access your front-end server, pull and replace the sensitive data with bogus data. If your front-end server needs that sensitive data, which is likely, use a special method that uses a different database user (that has access) to pull it from the back-end server. Someone would have to completely own your machine to figure this out... and it would still take enough time that you should be able to pull the plug. Most likely, they'll pull all your data before realizing it's bogus... ha ha.
I wish I had a good solution on how to protect your customers better to avoid CSRF. But what you have looks like a pretty good deterrent.
This question over on Security Stack Exchange has some useful discussion on the subject.
I especially like #AviD's answer:
Don't.
-
Most common frameworks have this protection already built in (ASP.NET, Struts, Ruby I think), or there are existing libraries that have already been vetted. (e.g. OWASP's CSRFGuard).

Resources