Safeguard
Application Security•

CWE-602: Client-Side Enforcement of Server-Side Security

If the server trusts the browser or app to enforce a rule, an attacker simply changes the client. Why every check must be repeated on the server.

Safeguard Security Team
4 min read

CWE-602 is a design weakness: the server relies on the client to implement a mechanism that is meant to protect the server. Anything running on a machine the attacker controls can be changed by the attacker.

It affects web apps with form validation, mobile apps with built-in rules, and industrial systems with thick clients.

How it happens

The classic form is a limit enforced only in JavaScript or in app code: a maximum quantity, a coupon rule, a file type check, a hidden form field holding a price or a role.

// Client side only
if (file.name.endsWith(".png")) { upload(file); }
# Server trusts whatever arrives
@app.post("/upload")
def upload():
    save(request.files["f"])     # no check here, the browser "already did it"

An attacker skips the page entirely and talks to the server with a script or a modified client.

MITRE's observed examples show the range.

  • CVE-2024-50653: an e-commerce product had a front-end restriction for coupon use, but the server did not restrict the number of requests for the same coupon.
  • CVE-2022-33139: a SCADA system used only client-side authentication, allowing adversaries to impersonate other users.
  • CVE-2006-6994: an ASP program allowed upload of .asp files by bypassing client-side checks.
  • CVE-2007-0163: steganography products embedded password information in the carrier file, which could be extracted from a modified client.

What an attacker gains

The consequences depend on what the mechanism was protecting.

  • Bypassing validation. Client-side checks can be easily bypassed, so malformed or unexpected input reaches the application as if it were trusted. This can lead to unexpected states, and possibly a crash.
  • Privilege escalation. Client-side authentication checks can be bypassed, letting clients raise their access level and perform unintended actions.

How to find it

MITRE points to testing that interacts with the live system: fuzzing and fault injection with many diverse inputs, and manual analysis such as penetration testing, threat modelling, and tools that let a tester record and modify an active session.

The cheapest check you can do yourself: take every rule you see enforced in the browser, and send a request that violates it directly to the server with curl or a proxy. If the server accepts it, you have found the weakness.

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

How to fix it

  1. For any security check performed on the client, duplicate it on the server. Attackers can modify values after the check or change the client to remove it.
  2. Keep the client checks anyway, for their secondary benefits. They help detect intrusion (the server sees input the client should have rejected), give users quick feedback, and cut server work on accidental errors.
  3. If some trust is needed between the two sides, use integrity checking and strong authentication to make sure inputs come from a trusted source.
  4. Manage that trust in one central place, so an implementer cannot forget a check on one code path.
@app.post("/upload")
def upload():
    f = request.files["f"]
    if not f.filename.lower().endswith(".png"):
        abort(400)
    save(f)      # and verify content type and size here too

Quick check

If client-side checks are bypassable, why keep them? They give users fast feedback, reduce wasted server work, and let the server notice attacks when it receives input the client would have rejected. They are not a security boundary.

What is the simplest test for this weakness? Send a request that breaks the client-side rule directly to the server. If it is accepted, the server is not enforcing the rule.

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.