CWE-863: Incorrect Authorization — When Users Can Do What They Shouldn’t

Authentication answers who a user is. Authorization answers what that user is allowed to do. Applications that authenticate users correctly but fail to enforce authorization consistently create one of the most common and dangerous classes of business logic vulnerabilities.

CWE-863 occurs when software does not properly verify that a user, process, or actor has permission to perform the requested action.

In practical terms:

The application lets authenticated users access or modify resources they are not authorized to use.

This article breaks down how incorrect authorization vulnerabilities occur, why developers still introduce them, modern exploitation techniques, framework-specific mitigations, and secure coding patterns.

What Is Incorrect Authorization?

Incorrect Authorization happens when an application performs an action without adequately checking whether the caller has permission.

Unsafe example:

@app.route("/admin/delete-user")
def delete_user():
    user_id = request.args["id"]
    delete_account(user_id)

If the endpoint lacks authorization checks, any authenticated user may delete arbitrary accounts.

How Incorrect Authorization Actually Works

The core issue is failing to enforce access control at the point of action.

Attack Flow

  1. User authenticates normally
  2. User discovers protected functionality/resource
  3. Application checks authentication but not authorization
  4. Action executes without permission validation
  5. Unauthorized access or modification occurs

Visual: Authorization Failure Data Flow

1. Authenticated User Valid Session 2. Requests Action Protected Resource 3. Missing / Weak Check No Enforcement 4. Result Unauthorized Access

Why Developers Still Get Authorization Wrong

Confusing Authentication with Authorization

Developers often check only:

if current_user:

instead of verifying permissions.

Client-Side Enforcement

UI restrictions are mistaken for security controls:

  • Hidden buttons
  • Disabled menu items
  • Frontend route guards

Attackers bypass the client entirely.

Inconsistent Enforcement

Authorization exists in some code paths but not others.

Complex Permission Models

RBAC/ABAC/ownership logic grows difficult to maintain.

“Internal Endpoint” Assumptions

Developers trust:

  • Admin panels
  • Internal APIs
  • Service-to-service calls

These assumptions routinely fail.

Modern Exploitation Techniques

Vertical Privilege Escalation

Regular user performs admin-only actions.

Horizontal Privilege Escalation

User accesses peer data/resources.

API Abuse

Hidden/undocumented endpoints lack checks.

Forced Browsing

Attackers manually access privileged URLs.

Parameter Tampering

Modify IDs/roles/resources in requests.

Visual: Authorization Exploitation Chain

AuthZ Failure Privilege Escalation Data Exposure Unauthorized Actions Business Compromise

Framework-Specific Mitigations

Enforce Authorization Server-Side

Never trust frontend/UI restrictions.

Centralize Authorization Logic

Use middleware/policies/guards:

  • Route guards
  • Policy objects
  • Permission decorators
  • Central access services

Check Object Ownership Explicitly

Unsafe:

invoice = Invoice.get(id)

Safer:

invoice = Invoice.get(id=id, owner=current_user.id)

Deny by Default

Require explicit permission grants.

Secure Coding Examples

Unsafe

if (user.loggedIn) {
    deleteUser(targetId);
}

Safer

if (user.role === "admin") {
    deleteUser(targetId);
}

Better

Use policy-based access control:

authorize(current_user, "delete_user", target_user)

Centralized and reusable.

Defense in Depth

Log Authorization Failures

Track denied actions for:

  • Detection
  • Forensics
  • Abuse monitoring

Test for Forced Browsing / IDOR

Authorization bugs often hide in overlooked endpoints.

Review Every Sensitive Action

Authorization should protect:

  • Read
  • Write
  • Delete
  • Export
  • Admin/config actions

Include Authorization in Threat Modeling

Developers often focus on authentication and forget permission boundaries.

Final Thoughts

Incorrect Authorization is dangerous because it undermines trust boundaries even when authentication works perfectly.

It persists because:

  • Developers conflate identity with permission
  • Client-side controls create false confidence
  • Permission logic becomes fragmented
  • Complex business rules evolve faster than enforcement

The core lesson is simple:

Knowing who the user is does not tell you what they should be allowed to do.

Every sensitive action requires explicit authorization—not just authentication.