Is it possible to prevent CSRF by checking the Origin and Referer headers? Is this adequate, provided that requests with neither are blocked?


4 Answers 4


Expanding on the answers of @Sjoerd and @lindon.

Origin vs Referer vs CSRF token

Most likely, the reason OWASP recommends also using a CSRF token, is that at the time when this recommendation was made - a significant portion of browsers did not yet support the Origin header. This is no longer the case, but people are chimpanzees.

In order to preserve privacy, any browser request can decide to omit the Referer header. So it is probably best to only check the Origin header. (In case you want to allow for users to preserve their privacy)

The Origin header is null in some cases. Note that all of these requests are GET requests, which means they should not have any side effects.

As long as you make sure the malicious website sending the requests with your browser cannot read the responses, you should be fine. This can be ensured using proper CORS headers. (Do not use Access-Control-Allow-Origin: *!)

To prevent "click-jacking", set the header X-Frame-Options: DENY. This will tell your browser that it is not allowed to display any part of your website in an iframe.

The "new" approach

Setting Cookie properties SameSite=lax or SameSite=strict will prevent CSRF attacks. This is a quite new feature though, and cannot be used alone, simply for the reason that not all common browsers support it yet. You can track support HERE.

When the browsers do, people will likely still recommend checking Origin/Referer/CSRF tokens. If they do - without giving a good reason, it is likely because they are chimps.

  • 2
    according to MDN, Edge doesn't send the Origin header with POST requests
    – Razor
    Commented Mar 24, 2019 at 17:42
  • 1
    @Razor: That is a very good point! Edge 16-18 does support the SameSite cookie property. Those using Edge 12-15 (0.13% globally at the time of this comment) would be vulnerable to CSRF attacks for websites not using tokens. Commented Mar 25, 2019 at 18:56
  • 1
    Beware that Origin header is not always sent for requests on the same origin.
    – Alireza
    Commented Jun 13, 2020 at 11:05
  • 1
    @TobiasBergkvist A bit of respect for chimpanzees, please. SameSite is only meant as a defense-in-depth measure precisely because it doesn't prevent all types of cross-origin abuse: jub0bs.com/posts/2021-01-29-great-samesite-confusion
    – jub0bs
    Commented Mar 27, 2021 at 12:19
  • 2
    SameSite with lax cannot protect against all csrf attacks. datatracker.ietf.org/doc/html/… From the link: 1. "Attackers can still pop up new windows or trigger top-level navigations in order to create a "same-site" request" 2. "Features like "<link rel='prerender'>" [prerendering] can be exploited to create "same-site" requests without the risk of user detection."
    – jacob
    Commented Jun 23, 2022 at 18:11

Yes, this is secure.

However, the referer header is not exactly mandatory, so there may be browsers or proxies than don't send a referer header. This would mean that these clients can't access your web site.

With the introduction of referrer policy it is possible to remove the referer header from a forged request. So to protect against CSRF it is necessary to block any requests that are missing a referer (and origin) header.

Edit: This paper has some numbers on what portion of clients omit a referer header.

  • What about referer header and HTTPS? If site is hosted on HTTP and CSRF is initiated from HTTPS site, there will be no referer header to check. Commented Apr 25, 2017 at 9:34
  • If site is hosted on HTTP then you are insecure be definition.
    – Demi
    Commented Apr 27, 2017 at 16:11
  • 2
    I think one could construct a case where even a non-zero Referer should not be trusted: If the target site T contains a link to some external site X (or embeds a resource like an image from this site, e.g. an avatar) and an attacker can make modifications to site X then the request from site T to site X (containing a Referer from T) could be answered with a HTTP redirect back to site T but with some malicious action in the URL. In this case T sees a request with a Referer of T and trusts it, even though the target URL at T is controlled by X. Commented Oct 23, 2017 at 12:43
  • 1
    @SteffenUllrich That is an excellent point! Of course, GET requests should be idempotent so that it doesn't matter if they're "forged" because they don't change any state, but people mess that one up all the time (including expecting POST requests but allowing GETs to that endpoint as well).
    – CBHacking
    Commented Nov 8, 2018 at 20:37
  • Why checking Origin``header alone is not enough? And also, by checking these headers, do you mean validating that the requests Origin` header matches the ones you whitelisted in the application?
    – eddyP23
    Commented Nov 12, 2018 at 11:11

If you want to rely on the Origin header to prevent XSRF, I suggest deploying the front-end and back-end application on different origins like www.example.com and api.example.com. In this case, the Origin header should be included with every modern browser. In addition, api.example.com can then reject any request with a missing Origin header.

If the above separation is not possible, i.e. because front-end and back-end is one application, a missing Origin header probably needs to be allowed by the server to prevent breaking the application (since the Origin headers is missing for same origin requests). Such a policy would then allow cross origin XSRF requests with very old browsers not attaching the Origin header. But at least victims with a modern browser should still be safe.

Also consider using CORS in combination with non simple requests for any critical request to prevent XSRF.


The accepted answer covered most of the things already. However, there is special case where you still need CSRF token even if you SameSite=strict is enable.

For example, website A lets users post contents and embed image source from wherever they want. Then, malicious user can insert an image with src=website-a.com/remove/something. This image is shown in website A, therefore, when normal users browse to this image, request initiated from this image is same origin with website A.

One problem is, request initiated from image a GET request, most action APIs are POST. However, Malicious user can often convert request from POST to GET and server still accept it, which makes CSRF attack possible.

  • In this case do you need a CSRF token or do you need to ensure that GET requests don't change state? Seems like either would suffice and that the latter might be preferable, especially since frameworks like ASP.NET Core don't validate the antiforgery token by default on GET requests. Commented Mar 4, 2023 at 11:52
  • 2
    @ChaseMedallion, we need to ensure GET requests don't change state. Because if they do, there are more problems than just CSRF. For example, rate-limiting protection usually works with POST requests only. If attacker can change state with GET requests. They can bypass rate-limit and spam servers with heavy loads. Commented Mar 17, 2023 at 2:55

You must log in to answer this question.

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