Safeguard
Application Security•

CWE-784 Reliance on Cookies without Validation in Security Decisions

If a cookie says you are admin and the server believes it, anyone can be admin. See how CWE-784 works and how to sign or replace cookie-based trust.

Safeguard Security Team
3 min read

CWE-784 covers a protection mechanism that depends on the existence or value of a cookie, without checking that the cookie is valid for the user who sent it. The cookie is treated as proof. It is only a claim.

Any web application that keeps a role, a login flag or a user ID in a plain cookie is exposed.

How it happens

A cookie lives on the client. MITRE puts it simply: attackers can easily change cookies in the browser or by writing client code outside the browser. If the server reads admin=1 and acts on it, the attacker only needs to add that cookie.

The record lists several observed cases:

  • CVE-2009-1549: an attacker could bypass authentication by setting a cookie to a specific value.
  • CVE-2009-1619: an attacker could bypass authentication and gain admin privileges by setting an admin cookie to 1.
  • CVE-2009-0864: a content management system granted admin privileges when a login cookie was set to OK.

A vulnerable Flask handler:

@app.route("/admin")
def admin():
    if request.cookies.get("admin") == "1":    # client controls this
        return render_template("admin.html")
    abort(403)

Test it from a terminal and it takes one header to get in:

curl -b "admin=1" https://example.test/admin

What an attacker gains

The record lists bypass of protection mechanisms and gaining privileges or assuming identity. It warns that it is dangerous to use cookies to set a user's privileges, because the cookie can be manipulated. In practice that means authentication bypass, privilege escalation, and acting as another user.

How to find it

  • Search code for cookie reads that feed an if statement guarding something sensitive.
  • Look in your browser developer tools at the cookies your site sets. Names like role, admin, isLoggedIn or userId with readable values are warning signs.
  • Edit those values by hand and see whether the application changes behavior.
  • A web application scan can flag predictable and unsigned session values.

How to fix it

  1. Keep authority on the server. Store the session in server-side state and put only a random, unguessable session ID in the cookie.
  2. Look up role and permissions from the server-side record on every request.
  3. If you must keep data in the cookie, sign it with a secret key and verify the signature, and encrypt it if it contains anything private. Reject any cookie that fails verification.
  4. Set the Secure, HttpOnly and SameSite attributes.
  5. Re-check authorization on each sensitive action, not just at login.
user = session_store.get(request.cookies.get("sid"))
if user and user.role == "admin":
    return render_template("admin.html")
abort(403)

Try it yourself

Dynamic scanning is one way to catch trust placed in client-controlled values. Walk through a scan of a web application.

Click through it at your own pace, or open it full screen.

Quick check

Is it safe to store the role in a cookie if the cookie is HttpOnly?

No. HttpOnly stops scripts in the page from reading it, but the user can still send any cookie value from their own client.

What does a signed cookie prove?

That the value was issued by the server and not altered. It does not hide the value, and it should still be checked against current server-side permissions.

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.