I know that there are a myriad of defenses against CSRF attacks. CSRF, however, is strictly a browser vulnerability, and any request that comes from a non-browser is "automatically" (and rightly so) allowed through.

But...how do you know whether a request is from a browser or not? As far as I can tell, the only way is by examining the user-agent header.

This is all well and good, but, unlike the Origin and Referer headers, the user-agent header can be modified programmatically:

Note: The User-Agent header is no longer forbidden, as per spec — see forbidden header name list (this was implemented in Firefox 43,) so can now be set in a Fetch Headers object, via XHR setRequestHeader(), etc.


Is there some other way of determining whether a request came from a browser? Or, to defend against CSRF attacks, are you just doomed to block all non-browser requests as well?

  • 3
    In general, CSRF attacks only work if the request is sent with appropriate headers (cookies, auth headers, etc), which normally only happens in a browser. If they don't come with the other bits, they're not going to have much affect - it shouldn't be possible for an attacker to actually read the appropriate data to affect someone else's session. I'm guessing there is some other context here which isn't included in the question...
    – Matthew
    Dec 7, 2016 at 12:34
  • 1
    What kind of non-browser origined requests are you expecting? And why should it be protected against CSRF?
    – Mr. E
    Dec 7, 2016 at 12:35
  • None of these answers address the actual question. Right now, the highest voted answer says: > If there is no browser, there is no attack. So just let the non > browsers through. That's true, but does not answer the question. In fact, it restates what was in the original question: > CSRF, however, is strictly a browser vulnerability, and any request that comes from a non-browser is "automatically" (and rightly so) > allowed through. The question was asking how applications can defend against attackers who abuse this behavior by pretending to not be browsers to get free access to the site --
    – ineedahero
    Dec 7, 2016 at 13:59
  • 1
    No, it isn't... It asks about defending against CSRF attacks, which won't give access to the site. If not providing a referrer allows access to the site, that's a different issue, but it's not CSRF.
    – Matthew
    Dec 7, 2016 at 14:08
  • The question is: "how to defend CSRF against requests that pretend not to be browsers". Clearly, this is a concern about requests that originate from browsers but spoof the user-agent header to pretend not to be from browsers, and thereby pass through undetected.
    – ineedahero
    Dec 7, 2016 at 14:17

5 Answers 5


If I read you right you are considering a scenario where the site http://completely.not.evil.com has a script like this embedded:

var req = new XMLHttpRequest();
req.setRequestHeader("User-Agent", "Totally not a browser");
req.open("POST", "http://example.com/delete_account");

This attack will fail. All the other answers says valid things about CSRF, but none of them mention the missing piece of the puzzle that explains why the attacker can not fool the victims browser to send a request with a modified user agent. And that piece is CORS.

Setting the User-Agent header will make the browser do a pre-flight OPTIONS request to the server to see if this is allowed. Unless you specifically configure your server to allow this - which would be shooting yourself in the foot - it will not respond positively. The browser will then not send the POST request that would have actually performed the malicious action.

So, in conclusion, the attacker can not succesfully modify the User-Agent header unless you allow her to do so.


You shouldn't need to block non browser requests.

The reason? Csrf is an attack on a user using a browser. They need to be visiting your site at the same time as a malicious site.

If there is no browser, there is no attack. So just let the non browsers through.

Update: After Anders' comment I now realise the question was relating to websites that already allow through state changing requests based upon User Agent. Please see his answer as it sums up the situation nicely in respect of this.

My new answer:

The best approach isn't to use a browser based authentication mechanism for sensitive functions. For anything accessed outside of a browser, enforce access using API keys sent as headers within the request. Automated systems using APIs shouldn't be using a username & password and gaining a session token, they should have a strong key that could be attached with every request.

This way it does not matter what the User Agent is - you identify non-browsers by the fact they are using an API key sent in a header to authenticate themselves.


I think an example of a CSRF attack could help understand why it's a browser based attack and why there is no need to detect if the client is using a browser or not.

Lets say you are a user of a website www.example.com and it is possible to delete your account if you click on a link that leads to www.example.com/delete_account. What happens when you click on that link? Your browser will generate a HTTP request to that resource (/delete_account) and include all you cookies for that site in that request. The server will therefore, based on the included cookies, know that it is you and that you want to delete your account, and will therefore do so.

The problem is that somebody could create a malicious page, and include an iframe with the src attribute pointing to www.example.com/delete_account. If you visit that malicious site, and are logged in to www.example.com, your browser will try to render the iframe by sending a request to www.example.com/delete_account and will also include your cookies in that request. By that, it would actually delete your account at example.com if there is no CSRF protection.

That means that CSRF happens if you for example trust a users action only based on the cookies that he sends, and the problem is that Browsers send cookies automatically. That's why CSRF protection is important.

Could I make you perform the same request to www.example.com/delete_account using a non-browser? That would actually make no sense. I could try to convince you to copy paste the request into Burp, and additionally you would have to manually copy paste your cookies into the request... and it actually makes no sense :) Best way to understand it is not to think how the protection would work, but to think how the attack would work.

  • To which I would say to you, actions that change state on the server must use POST. The HTTP RFC literally says that a state change on the server from a HEAD or GET is not the responsibility of the browser.
    – Joshua
    Apr 3, 2019 at 15:45

In short: you don't have to worry about CSRF and non-browsers.

To a CSRF attack to succeed, your website must receive a request with all headers and cookies from a client, and not be able to tell if your site or a third party made the request.

To a non-browser attack a user, it would have to guess (or possess) all the cookies and headers your site uses, passing all session information as if the user was connecting.


You don't have to worry about the user agent being messed with because

CSRF doesn't come from an attacker

The forged requests involved in a CSRF attack are not issued by the attacker. They are issued by a legitimate user's browser. That is the whole point of it. The hacker is hijacking the legitimate user's legitimate session (that is why the attack is sometimes called session riding). The attacker merely convinced the user to send the request somehow (e.g. by clicking a link or opening a carefully crafted email); he is not actually involved in the traffic or the network connection in any way.

The idea that the attacker would forge a user-agent header and send the request does not fit into this scenario at all. Certainly there are other attacks that can be issued directly by a hacker, using a hacking tool of his choice, but none of those attacks are CSRF, by definition.

You must log in to answer this question.

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