59

I've seen several blanket statements on the web to the effect that you don't need CSRF protection for GET requests.

But many web applications have GET requests that return sensitive data, right? Then wouldn't you want to protect those against CSRF attacks?

Am I missing something, or are these blanket statements assuming that the data the GET request gives is unimportant?

Examples of blanket recommendations gainst using CSRF tokens with GET:

5 Answers 5

60

CSRF protection is only needed for state-changing operations because of the same-origin policy. This policy states that:

a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin.

So the CSRF attack will not be able to access the data it requests because it is a cross-site (that's the CS in CSRF) request and prohibited by the same-origin policy. So illicit data access is not a problem with CSRF.

As a CSRF attack can execute commands but can't see their results, it is forced to act blindly. For example, a CSRF attack can tell your browser to request your bank account balance, but it can't see that balance. This is obviously a pointless attack (unless you're trying to DDoS the bank server or something). But it is not pointless if, for example, the CSRF attack tells your browser to instruct your bank to transfer money from your account to the attacker's account. The success or failure page for the transfer is inaccessible to the attacking script. Fortunately for the attacker, they don't need to see the bank's response, they just want the money in their account.

As only state-changing operations are likely to be targets of CSRF attacks, only they need CSRF defenses.

5
  • so what step should I take to prevent this CSRF attack ??
    – hud
    Commented Dec 11, 2018 at 10:01
  • 6
    However, this is not true if CORS is involved, is it? E.g. I have a GET request that returns sensitive data and is CORS enabled, it can be read by a malicious site, or a trusted site that has been compromised by say an XSS.
    – Leprechaun
    Commented Mar 6, 2020 at 10:15
  • 1
    Note that you may want to add CSRF protection against GET requests, even if they don't change state, if you want to prevent timing attacks. For example, you can use timing attacks to extract information from Lucene: idontplaydarts.com/2015/09/…
    – priomsrb
    Commented Sep 15, 2020 at 7:32
  • We have a very strict same-origin policy enabled, but a recent pen-test nevertheless recommended we implement CSRF to protect older browsers that don't support same-origin policies, as these are known to be in use by a subset of our users. Does your advice about GET requests change if same-origin policies are not being enforced?
    – HappyDog
    Commented Jul 6, 2021 at 15:37
  • Without the same-origin policy, an attacker could potentially extract user-specific data (ie: data that requires authentication) via a cross-site GET request. Adding CSRF protection to GETs will protect against this. I suspect that lack of same-origin policies leads to other security problems. If possible you should force the users to upgrade. (I know - it's complicated.) Commented Aug 2, 2021 at 14:51
31

Ordinarily safe methods do not have to be protected against CSRF because they do not make changes to the application, and even if they're returning sensitive information this will be protected by the Same Origin Policy in the browser.

If your site is implemented as per standards, your GET requests should be safe and therefore do not need protection.

However, there is a specific case where a "Cross-Site DoS"* attack could be executed. Say your reporting page takes 10 seconds to execute, with 100% CPU usage on your database server, and 80% CPU usage on your web server.

Users of your website know never to go to https://yoursite.example.org/Analysis/GetReport during office hours because it kills the server and gives other uses a bad user experience.

However, Chuck wants to knock your yoursite.example.org website offline because he doesn't like you or your company.

On the busy forum he posts to often, http://forum.walkertexasranger.example.com, he sets his signature to the following:

<img src="https://yoursite.example.org/Analysis/GetReport" width=0 height=0 />

He also know that your company employees frequent the forum, often while also logged into yoursite.example.org.

Every time one of Chuck's posts are read by your employees, authentication cookies are sent to https://yoursite.example.org/Analysis/GetReport, so your site processes the request and generates the report, and your system goes offline because CPU is eaten by these constant requests.

So even though the request is a GET request and doesn't make any permanent changes to your system (aka "safe"), it is infact bringing down your system every time it is ran. Therefore, it would be better to protect this with a CSRF prevention method.

*XSDoS, or Cross-Site Denial if Service, is a phrase coined by me, so don't go Googling for it.

4
  • You mention bypassing the CSRF protection by using an img tag. I'm curious. If https://yoursite.example.org/Analysis/GetReport actually returned an image of some sensitive report (a JPG for example), would the image load? Is there any way to protect against this?
    – jmrah
    Commented Jul 18, 2020 at 15:06
  • 2
    Yes it would load if the content type was an image type and it was a valid image. Yes, you could protect this with a csrf token and only run the report code which generated the image if the token is valid. Commented Jul 19, 2020 at 7:07
  • 2
    Of course the user world need to be logged into yoursite.example.org to see the image on the forum, so they're not seeing anything that they wouldn't normally have permission to. However, it'd be out of context and Chuck maybe could use the image to trick employees that he has the data himself. Therefore social engineering is needed too so this scenario is less likely. Commented Jul 19, 2020 at 7:16
  • I forgot for a moment that Chuck wouldn't be able to see the image or actually access it in any way. Thanks for your reply.
    – jmrah
    Commented Jul 19, 2020 at 10:32
9

CSRF protection is not used to protect data. It is used to protect a user from unknowingly changing state, such as transferring money or logging out of an account.

Thus, if your GET request is changing a state (which it shouldn't be), then you should have CSRF protection. But if it's just returning data, it doesn't need CSRF protection, because CSRF protection wouldn't protect anything in this case.

It may help to go over this page again: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29

10
  • 1
    Please don't confuse visitors with the controversial CSRF logout issue.
    – h4ckNinja
    Commented Feb 26, 2016 at 3:07
  • @Micheal I'm curious how it is controversial? I haven't heard of it being controversial.
    – d1str0
    Commented Feb 26, 2016 at 3:09
  • It is controversial because logouts, while state-changing, occur over GET normally, so what are you supposed to do with the anti-CSRF token? Some consider it an issue, some don't. Google for example won't accept bug bounty reports with it. My vote is leave it at changing the account settings.
    – h4ckNinja
    Commented Feb 26, 2016 at 3:14
  • It's trivial to implement and it does offer benefit. GET can handle CSRF tokens just fine.
    – d1str0
    Commented Feb 26, 2016 at 3:26
  • 1
    But you shouldn't put anti-CSRF tokens in the GET, because they'll end up in browser history, proxy logs, and server logs.
    – h4ckNinja
    Commented Feb 26, 2016 at 3:30
2

CSRF, or Cross-Site Request Forgery, isn't about protecting data from being retrieved, but protecting data from being changed. This is also referred to as state changes. In an application, state changes can include profile data, like the email address, user password, or biography, or transferring funds.

GET requests are to be used for idempotent requests, or requests that do not change state. These requests do not need to have anti-CSRF tokens.

POST requests are to be used for non-idempotent requests, or requests that do change state.

1
  • Idempotent request means something else! Idempotent operation means it doesn't matter if I run operation once, or multiple times. For example mySet.add(data) is ideponent, but myArray.add(data) is not - multiple calls for adding element to array will produce duplicates. Idempotent requests can change state! For example deleteUserById(5). In fact, there is not so often used term "nullipotent" which means: it doesn't matter if I run operation zero, or multiple times.
    – Mino
    Commented Nov 25, 2020 at 10:39
0

Generally, POST requests should be used for changing the state of something. If you have GET requests set up so that they can change the state (e.g. www.example.com/settings?delete_account=True), then you should use CSRF protection as a Band-Aid fix.

Try to use POSTs to change the state, not GETs.

1
  • 1
    This answer is dangerous for future readers - No, using POST requests does not protect you from CSRF. It is very easy to setup a form with method=POST and have it onload submit, so POSTs are just as bad as GETs. It's made worse with Flash or old browsers that can even send JSON over POST. Commented Oct 22, 2018 at 18:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .