Technically speaking, it is possible to spoof both headers using an intercepting proxy but that's useless because we are doing it ourselves as an attacker.

When we send an ajax request using JS from another domain with our spoofed referer and origin header it won't really be spoofed. The browser would still send the legit header to the server.

My question is, why is it so that we can't spoof both these headers while sending cross domain requests?

  • Are you asking why these headers cannot be set (because the specification says so) or are you asking what the intend is that the specification says so (to prevent attacks)? Dec 9, 2019 at 20:16
  • 2
    Because the browser says so Dec 9, 2019 at 20:21
  • 3
    Could you elaborate what you mean by "why"? It's simply a browser design decision. Browser vendors agreed that certain security restrictions should apply to certain headers.
    – Arminius
    Dec 9, 2019 at 20:22
  • Grandma uses a browser, not the command line. browsers disallow a lot of risky behavior to cut down on zombie attacks that command-line tools (for example) don't have to normally contend with.
    – dandavis
    Dec 9, 2019 at 22:41

2 Answers 2


You can't set those headers, because the browsers ignore attempts to set them. Browsers ignore attempts to set them, because they aren't supposed to be script-controlled. The restriction on letting them be script-controlled is for security reasons. If you could set the Origin header, you could break the security guarantees of CORS. Since the whole point of CORS is to open gaps in the same-origin policy for trusted origins only, letting a script (which can be attacker-controlled) spoof the origin is obviously unsafe.

Another question would be: why should XHR/Fetch allow you to set those headers? What legitimate reason is there to do that? There's a good reason to disallow it (breaks a security guarantee, setting us back to the bad old days of JSONP where you couldn't be sure who sent the request), and no good reason to allow it, so of course it's not allowed.

  • Can you spoof them via a terminal executable, like bash? I tried and it actually works :/ curl 'https://myapi.com/api' \ -H 'authority: SPOOFED AUTHORITY' \ -H 'accept: application/json' \ -H 'accept-language: en-US,en;q=0.7' \ -H 'origin: SPOOFED URL' \ -H 'referer: SPOOFED URL/' \ -H 'sec-fetch-dest: empty' \ -H 'sec-fetch-mode: cors' \ -H 'sec-fetch-site: cross-site' \ -H 'sec-gpc: 1' \ -H 'user-agent: MyUserAgent' \ --compressed Jan 1 at 21:03
  • 1
    Obviously you can - HTTP is just text (OK, HTTP2 is binary, but that doesn't actually matter here); I can open literal telnet to a website and send whatever HTTP I want, including Origin and other headers. The OP actually alludes to this with their point about intercepting proxies. That's totally irrelevant to the question though, because the entire point is to get the victim's browser to change these headers (because the victim's browser has the session and anti-CSRF tokens). You aren't attacking the server, here; you're attacking a user so you need to do it through their browser.
    – CBHacking
    Jan 2 at 8:50
  • I see. I had the impression that CORS was more of a safety measure for the server, but it is aimed to protect the client from some attack (which I still ignore how it would look like) if I understand you correctly. I guess is hard to prepare for something that you do not understand entirely...thanks for the clarification btw. Jan 3 at 6:29
  • 1
    @nicoramirezdev You should go read about CSRF, but the short version is: imagine a website X that uses cookies for session authentication. That is, the user logs into X, the server generates a token (random/JWT/etc.), and sends it to the user in a cookie. The user's browser will send that cookie to the server for that site on every single request to X... no matter the source of the request (note: samesite is changing this). So if you're logged into site X and visit malicious site Y, a script on Y can force you, unknowingly, to take an authenticated action (e.g. send money to someone) on X.
    – CBHacking
    Jan 3 at 7:37

These headers cannot be modified as a safety precaution, the ability to alter them would break a lot of assumptions about how browsers work. There used to be some bugs in flash that would let you do this: https://www.securityfocus.com/archive/1/441014/30/0/threaded

You must log in to answer this question.

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