Loading...
Why Your API Should Never Trust user_id from the Client

Why Your API Should Never Trust user_id from the Client

How secure systems use authentication context instead of request data to prevent broken access control and real-world data breaches.

Shahid Malik
Shahid Malik20 Jan, 2026 · 7 min read

Introduction

One of the most common mistakes in backend systems is also one of the most dangerous.

Many APIs accept a user_id directly from the client request. It looks harmless. The user is already logged in, after all. So what could go wrong?

In practice, this single design decision has caused some of the largest data leaks and authorization failures in modern software systems. The problem is not about coding skills. It is about understanding how trust boundaries work in distributed systems.

This article explains why passing user_id from the client is unsafe, how secure systems really identify users, and what industry standards and real incidents teach us about this pattern.

The Two Common API Designs

When building authenticated APIs, developers usually follow one of these two approaches:

Approach 1 – Client-Supplied Identity

The client sends:

json
{
  "user_id": 42,
  "action": "create_order"
}

The backend trusts this value.

Approach 2 – Token-Derived Identity

The client sends only the access token:

text
Authorization: Bearer <JWT>

The backend verifies the token and internally extracts the user identity.

The client never controls the user_id.

At first glance, both seem to work. From a security perspective, they are very different.

Why Trusting user_id is Dangerous

The main risk is a vulnerability called Insecure Direct Object Reference (IDOR).

It means the system allows a user to access or modify objects that do not belong to them by changing identifiers in the request.

Example:

A user logged in as ID 7 can simply send:

json
{
  "user_id": 1,
  "amount": 10000
}

If the backend trusts this value, the user is now acting as someone else.

This is not a theoretical problem.

IDOR is listed under OWASP API Security – Broken Object Level Authorization, one of the top causes of API breaches globally.

In multiple public security reports, IDOR has been responsible for:

  • Unauthorized data exposure
  • Account takeovers
  • Financial fraud
  • Privacy violations

The root cause is always the same: identity is taken from client input instead of server-side authentication context.

Tokens Exist for a Reason

Modern authentication systems use tokens (JWT, OAuth2, session tokens) to solve exactly this problem.

A token is:

  • Cryptographically signed
  • Tamper-proof
  • Issued only after successful authentication
  • Verified by the backend on every request

Inside the token, the server already knows who the user is:

json
{
  "sub": "42",
  "email": "user@example.com",
  "role": "user"
}

This value cannot be modified by the client without invalidating the signature.

This is why standards like OAuth 2.0, OpenID Connect, and RFC 7519 (JWT) define identity as part of the authentication context, not request data.

Zero Trust in Practice

A core principle of secure systems is simple:

Never trust the client for identity.

The network is untrusted.

The browser is untrusted.

The mobile app is untrusted.

Only the verified token is trusted.

When the backend derives user_id from the token, every endpoint automatically follows the same security rule. This drastically reduces the chance of missing authorization checks and introducing silent vulnerabilities.

How Secure APIs Are Designed

A safe request usually looks like this:

http
POST /api/orders
Authorization: Bearer <token>

Payload:
{
  "product_id": 15,
  "quantity": 2
}

Backend logic:

python
user = request.user
create_order(user_id=user.id, ...)

There is no user_id in the payload.

The server decides who the user is.

This is how large platforms like Google, Stripe, AWS, GitHub, and Auth0 design their APIs.

When is Passing user_id Acceptable?

There are limited and controlled cases:

  • Internal microservices
  • Admin systems
  • System-to-system integrations

Even here, the token must contain elevated privileges, and the backend must still validate authorization explicitly.

For public user-facing APIs, trusting user_id is almost always a security flaw.

Evidence from the Industry

Security incident analyses consistently show:

  • Broken Access Control is the #1 API vulnerability category.
  • IDOR flaws are among the most frequently exploited issues.
  • Most of these arise from trusting identifiers coming from the client.

These findings are published repeatedly in:

  • OWASP API Security Top 10
  • NIST Zero Trust Architecture guidelines
  • OAuth and OpenID security recommendations

The consensus is clear: identity must come from authentication context, not request parameters.

Conclusion

Accepting user_id from the client feels convenient, but it creates a fragile and dangerous trust model.

Deriving identity from the verified token is not only more secure, it is simpler to reason about, easier to maintain, and aligned with global standards.

If your API handles anything important — user data, money, permissions, or privacy — this is not an optional design choice. It is foundational security engineering.

Good APIs do not ask the client who they are.

They already know.