← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Broken Access Control

Security CWE-284 OWASP A1:2021 CVSS 8.8 PHP 5.0+ Intermediate
debt(d7/e7/b7/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The term's detection_hints list semgrep as the sole tool, but the metadata explicitly states automated=no and describes the pattern as a missing check — a static tool can flag routes lacking auth middleware but cannot reason about ownership semantics or IDOR logic. Most real instances surface only through careful code review or security testing, not automated scanning alone.

e7 Effort Remediation debt — work required to fix once spotted

Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix says 'check authorisation on every request server-side', and common_mistakes reveal the problem appears in middleware, API routes, admin controllers, and UI logic simultaneously. Fixing it properly requires auditing and patching every route and controller action — a cross-cutting change that cannot be isolated to one file or component.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (b7). The term applies_to web and api contexts broadly (not scoped to one component), and every new route, controller, or API endpoint added in the future must consciously implement and verify authorisation. The missing pattern exerts gravitational pull on all new feature development — every developer must remember to apply ownership checks on every resource operation, making it a persistent, wide-reaching structural concern.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field explicitly identifies that developers believe hiding UI elements (obscurity) constitutes access control. Additionally, common_mistakes show developers conflate authentication with authorisation, and assume sequential IDs are private. These are well-documented contradictions of intuition — the 'obvious' UI-hiding approach is always insufficient — but not quite catastrophic since the correct mental model (server-side checks) is broadly taught, placing it at t7 rather than t9.

About DEBT scoring →

Also Known As

BAC access control failure authorisation bypass

TL;DR

Failure to enforce what authenticated users are allowed to do — the #1 OWASP vulnerability, enabling privilege escalation and data exposure.

Explanation

Broken access control covers: horizontal escalation (accessing another user's data by changing an ID), vertical escalation (accessing admin functions as a regular user), missing function-level checks (assuming UI hiding is sufficient), insecure direct object references (IDOR), CORS misconfigurations, and JWT tampering. In PHP applications, enforce access checks server-side on every request — never rely on hidden form fields, client-side role checks, or obscure URLs. Centralise authorisation logic in a dedicated gate or policy class rather than sprinkling ad-hoc checks throughout controllers.

How It's Exploited

A user changes /api/invoices/1001 to /api/invoices/1002 and receives another customer's invoice because the controller queries by ID without checking ownership.

Diagram

flowchart TD
    USER[Logged-in User<br/>Role: viewer] -->|GET /api/users/42| APP[Application]
    APP -->|Check permission?| CHECK{Authorization
check}
    CHECK -->|No check!| DB[(Database<br/>returns any user)]
    DB --> LEAK[Data exposed<br/>IDOR vulnerability]
    subgraph Fix - RBAC
        REQ2[Request] --> AUTHZ[Check: does user<br/>own or have role<br/>for this resource?]
        AUTHZ -->|Yes| ALLOW[Allow]
        AUTHZ -->|No| DENY[403 Forbidden]
    end
    style LEAK fill:#f85149,color:#fff
    style ALLOW fill:#238636,color:#fff

Common Misconception

Hiding URLs or buttons in the UI prevents unauthorised access. Security through obscurity is not access control — any URL accessible to one authenticated user can be accessed directly by another, bypassing the UI entirely.

Why It Matters

Broken access control is the #1 OWASP vulnerability — it means users can access data or actions they should not. A single missing authorisation check can expose every record in your database to any authenticated user.

Common Mistakes

  • Hiding links in the UI instead of enforcing authorisation server-side — obscurity is not access control.
  • Checking authentication (are you logged in?) but not authorisation (are you allowed to do this?).
  • Using sequential IDs and assuming users will not guess other users' resource IDs (IDOR).
  • Applying access control in middleware but bypassing it in API routes or admin controllers.

Code Examples

✗ Vulnerable
// Access control only in the UI — not enforced server-side:
router()->get('/admin/users', [AdminController::class, 'index']);
// Middleware checks role for /admin/* in the UI
// But direct API call to /api/users/export has no role check
// Attacker bypasses UI, calls API directly — full data exposure
✓ Fixed
// RBAC check on every protected route:
public function show(int $id): Response {
    $resource = Resource::findOrFail($id);

    // Check ownership OR admin role:
    if ($resource->user_id !== auth()->id() && !auth()->user()->isAdmin()) {
        abort(403, 'Forbidden');
    }

    return response()->json($resource);
}

// Or policy-based (Laravel):
public function show(User $user, Resource $resource): bool {
    return $user->id === $resource->user_id || $user->isAdmin();
}
// Controller: $this->authorize('show', $resource);

Added 15 Mar 2026
Edited 22 Mar 2026
Views 77
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 4 pings T 5 pings F 3 pings S 5 pings S 4 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 2 pings M 0 pings T 1 ping W
Google 1
No pings yesterday
Scrapy 20 Ahrefs 9 Perplexity 7 Amazonbot 7 Google 4 ChatGPT 3 SEMrush 3 Meta AI 2 Claude 2 Bing 2 Unknown AI 1 Majestic 1 PetalBot 1
crawler 59 crawler_json 3
DEV INTEL Tools & Severity
🔴 Critical ⚙ Fix effort: Medium
⚡ Quick Fix
Check authorisation on every request server-side: does the authenticated user own or have permission for this specific resource?
📦 Applies To
PHP 5.0+ web api
🔗 Prerequisites
🔍 Detection Hints
Route or controller action with no auth middleware or missing ownership check on resource by ID
Auto-detectable: ✗ No semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: High ✗ Manual fix Fix: High Context: File Tests: Update
CWE-284 CWE-285 CWE-862 CWE-863


✓ schema.org compliant