Safeguard
Application Security•

CWE-293 Using the Referer Header for Authentication

The Referer header is set by the client, so it proves nothing. Learn why checking it as a login or authorization step fails and what to check instead.

Safeguard Security Team
2 min read

CWE-293 covers products that treat the HTTP Referer field as proof that a request is legitimate. MITRE puts it directly: the field can be easily modified, so it is not a valid way to check message integrity.

Web developers hit this when a page says "only accept this action if it came from our own form" and uses the Referer to decide.

How it happens

The Referer header tells a server which page the browser was on when it sent the request. A browser fills it in, but so does any script, proxy or command line tool, with any value its author likes. The server cannot tell the difference.

# Vulnerable: trusts a header the caller controls
@app.route("/account/delete", methods=["POST"])
def delete_account():
    if "example.com/settings" not in request.headers.get("Referer", ""):
        abort(403)
    remove_user(current_user())
curl -X POST https://example.com/account/delete \
  -H "Referer: https://example.com/settings"

One line of curl satisfies the check. (The example also skips checking that a user is logged in, which is the bigger problem.)

What an attacker gains

MITRE lists one consequence: actions that may not be authorized otherwise are carried out as if they were validated by the server referred to. In practice, an attacker gets to trigger privileged actions simply by sending the header the code expects.

How to find it

MITRE says automated static analysis (SAST) can find some instances by modeling data flow in source or compiled code. A quick manual pass also works: grep for reads of the Referer or Referrer header, then see whether the value feeds an allow or deny decision.

How to fix it

MITRE's guidance is to use authorization that cannot be simply spoofed, backed by strong authentication and protection of the method. For a web app that means:

  1. Authenticate the user with a session or token, and authorize each action server side.
  2. Protect state-changing requests with a per-session anti-forgery token rather than a header the client can set.
  3. If you still read the Referer, treat it as a log or analytics hint, never as a gate.

Quick check

Can the Referer header be trusted if my site is HTTPS only?

No. HTTPS protects the connection, not the honesty of the client. Any client can send any Referer value.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.