ZeroHour

CVE-2026-56828

niche

Authenticated privilege escalation in Shopper via misgated Livewire admin components

CVSS 3.1
8.8 high
EPSS
Published
()
Modified
AI analysis

Three Livewire admin components in ShopperLabs' Shopper e-commerce framework (shopper/framework) gate state-mutating actions with the read-only `view_users` permission instead of an administrative one (CWE-285/CWE-862), a residual gap from the v2.8.0 authorization fix in PR #511 (GHSA-f946-9qp6-vgch). A staff user holding only `view_users` and `access_dashboard` — a realistic support/viewer role per Shopper's own seeder — can invoke the affected actions, and the Permissions page even enumerates permission IDs in its wire:click handlers so no IDs must be guessed. An attacker can grant arbitrary permissions to their own role (self-escalation), create a new team member with an attacker-chosen password and the `admin` role and then log in as that account, or delete permission rows and removable roles (RBAC disruption). Any Shopper deployment that grants `view_users` to non-admin staff is affected, including the current v2.8.0 release whose own security commit introduced one of the vulnerable files. No public proof-of-concept, KEV listing, or known in-the-wild exploitation has been reported.

What to do: Inventory Shopper deployments and audit staff roles: revoke `view_users` from any non-admin staff, review role/permission rows and the team-member table for changes or accounts created by view-only users, and disable or reset any suspicious accounts. No patched release is identified in the data (v2.8.0 remains vulnerable); when an upstream fix ships, upgrade beyond it, and as an interim mitigation patch the three Livewire components to require `access_setting` (or an equivalent admin permission) for write actions such as togglePermission, removePermission, and CreateTeamMember::store().

Affected
ShopperLabs Shopper (shopper/framework composer package, admin Livewire components Permissions.php, CreateTeamMember.php, RolePermisv2.8.0 confirmed vulnerable (latest release; no patched version identified in the data). The Permissions and RolePermission components predate the v2.8.0 fix an
Estimated exposure
nichelikely at most low thousands of active deployments (niche self-hosted Laravel e-commerce package; no install telemetry in the data) — Shopper is a low-adoption, self-hosted Laravel e-commerce framework, and exploitation additionally requires an authenticated staff account with `view_users`, so the realistically exposed population is small; the provided data contains no…

Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.

Description

Shopper: privilege escalation via improper Livewire admin component authorization ## Summary Three Livewire admin components in `shopper/framework` (latest master at commit `fcd0c59`, released as v2.8.0) gate state-mutating actions on the read-only `view_users` permission. This is the same class as the issue Shopper fixed in v2.8.0 / PR #511 / [GHSA-f946-9qp6-vgch](https://github.com/shopperlabs/shopper/security/advisories/GHSA-f946-9qp6-vgch) — the PR moved most write actions from `view_users` to `access_setting`, but three were missed (one of them is a brand-new file added by the security commit itself). A staff user holding only `view_users` + `access_dashboard` (a realistic "support" or "viewer" role per Shopper's own `PermissionsTableSeeder`) can: (1) self-escalate by granting any permission to their own role; (2) create a brand-new admin team member with a chosen password and the `admin` role and then log in as that user; (3) delete arbitrary `permissions` rows (RBAC DoS) or — when `can_be_removed=true` — delete entire roles. CVSS 3.1: `AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H` = 8.8 (High). CWE-285 (Improper Authorization) + CWE-862 (Missing Authorization). ## Vulnerable components (paths relative to repo root) ### 1) `packages/admin/src/Livewire/Components/Settings/Team/Permissions.php` - `togglePermission(int $id)` at line 28 calls `$this->authorize('view_users');` - `removePermission(int $id)` at line 55 calls `$this->authorize('view_users');` The Permissions blade at `packages/admin/resources/views/livewire/components/settings/team/permissions.blade.php` line 34 emits every permission's `id` directly in `wire:click` handlers, so the attacker does not even need to guess IDs — the page itself enumerates them. Net effect: any user who can mount the Permissions component (gated on `view_users`) can grant any permission row to the bound `$role`. Granting `access_setting` to the attacker's own role unlocks every action that PR #511 supposedly hardened with `->authorize('access_setting')`. Granting `delete_customers`, `edit_orders`, `edit_products`, `add_brands`, etc. is direct data-modification escalation. ### 2) `packages/admin/src/Livewire/SlideOvers/CreateTeamMember.php` - `mount()` at line 53 calls `$this->authorize('view_users');` - `store()` at line 122 calls `$this->authorize('view_users');` This file is `new file mode 100755` in commit `fcd0c59` — it was created as part of the security fix and inherited the same misclassified gate. `store()` creates a `User` with `email_verified_at = now()`, the attacker's chosen password, and any selected `role_id`. The `Radio::make('role_id')` options filter only excludes `config('shopper.admin.roles.user')`, so the `admin` role is selectable. Log out, log in as the new account → full admin. ### 3) `packages/admin/src/Livewire/Pages/Settings/Team/RolePermission.php` - `deleteAction` at lines 81-90: only gated by `->visible($this->role->can_be_removed)`, with no `->authorize()` chain. Page-level `mount` (line 52) requires only `view_users`. For any role with `can_be_removed = true`, a `view_users`-only user can call the action and delete the role (cascading the loss of permissions for every assigned user). ## Self-confirmation in the project's own test suite The following tests are green on master @ `fcd0c59` — they ARE the PoC: ``` tests/Admin/Livewire/Components/Settings/Team/PermissionsTest.php line 14-16: `givePermissionTo('view_users')` only line 36-45: "can toggle permission to role" — passes line 74-85: "can remove permission" — passes tests/Admin/Livewire/SlideOvers/CreateTeamMemberTest.php line 16-18: `givePermissionTo('view_users')` only line 29-56: "can create new team member" — passes, asserts the new user `hasRole('manager')` ``` A `view_users`-only Livewire user actor successfully toggles permissions, removes permissions, and creates a new privileged user — verified by Shopper's own regression tests. ## Suggested fix Change `$this->author

Ecosystems
composer
Weakness
CWE-285, CWE-862
Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
GHSA
GHSA-j328-xmgp-j4q3 (high)

In the news

No ingested article mentions this CVE yet.