CVE-2026-56828: Shopper Privilege Escalation Vulnerability

HIGH
Advisory Identifier: GHSA-j328-xmgp-j4q3
CVSS 8.8
CWE-862 CWE-285
Published
Advisory Summary

CVE-2026-56828 is a HIGH (CVSS 8.8) privilege escalation vulnerability (CWE-862: Missing Authorization) affecting Shopper libraries in the Packagist ecosystem. The issue involves privilege escalation via improper livewire admin component authorization. Remediation is available by upgrading affected packages to version 2.9.2.

CVE-2026-56828 at a Glance

CVE Identifier CVE-2026-56828
GHSA Identifier GHSA-j328-xmgp-j4q3
Severity HIGH
CVSS v3.1 Base Score 8.8
CWE Classification CWE-862: Missing Authorization
Affected Product Shopper
Package Ecosystem Packagist
Published Date
Last Updated

Security Impact

CVSS: 8.8

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-56828

To remediate this vulnerability, upgrade all affected Shopper dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

shopper/framework fixed: 2.9.2
Upgrade shopper/framework to 2.9.2
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for shopper/framework

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-56828, inspect your project dependencies for Shopper:

inspect dependencies for shopper/framework

Analyze the terminal output to locate any version of Shopper in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.9.2), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-862: Missing Authorization, where the product does not perform an authorization check when an actor attempts to access a resource or perform an action. In Shopper, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## 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->authorize('view_users')` to `$this->authorize('access_setting')` in: - `Permissions::togglePermission` - `Permissions::removePermission` - `Permissions::mount` (defence in depth, matches `Team\Index`) - `CreateTeamMember::mount` - `CreateTeamMember::store` Add `->authorize('access_setting')` to `RolePermission::deleteAction` (matches the pattern already applied to `generatePermissionsAction`, `createPermissionAction`, and `Team\Index::DeleteAction`). Update the two regression tests to use `access_setting` instead of `view_users` so they accurately reflect the privilege boundary. ## Resources - Prior advisory of the same class: https://github.com/shopperlabs/shopper/security/advisories/GHSA-f946-9qp6-vgch - Fix commit that introduced these residual gaps: https://github.com/shopperlabs/shopper/commit/fcd0c5920588702df5b874f432b1042abd77a50b - CWE-285 Improper Authorization - CWE-862 Missing Authorization ### Credits Reported by Vishal Shukla(@shukla304) using sechub.dev AI Agent ### Support If this disclosure was useful and if users would like to support continued open-source security research and responsible-disclosure work, they can sponsor at https://github.com/sponsors/therawdev — Shoppers thanks those who keeping open source safe.

CVE-2026-56828 Affected Shopper Versions

1 component(s)
Fixed Versions:
2.9.2
Product / Package Ecosystem Affected Versions Fixed Version
shopper/framework
Packagist
≥ 2.8.0
< 2.9.2
2.9.2

References

Frequently Asked Questions

What is CVE-2026-56828?
CVE-2026-56828 is a security vulnerability in Shopper involving privilege escalation via improper Livewire admin component authorization under CWE-862: Missing Authorization.
Which Shopper versions are affected?
Affected versions include releases prior to 2.9.2 across affected packages: shopper/framework.
What version fixes CVE-2026-56828?
Upgrading to 2.9.2 (or the latest patched release for your respective branch) resolves the vulnerability.
Is shopper/framework affected?
Yes, shopper/framework is affected in releases prior to 2.9.2. Upgrade your dependency to 2.9.2 or later.
What is the CVSS score of CVE-2026-56828?
CVE-2026-56828 has a CVSS v3.1 base score of 8.8 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-56828?
CVE-2026-56828 is classified under CWE-862: Missing Authorization (The product does not perform an authorization check when an actor attempts to access a resource or perform an action.).
How can I check Packagist dependencies for CVE-2026-56828?
Run the dependency tree command: 'inspect dependencies for shopper/framework'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-j328-xmgp-j4q3",
  "modified" : "2026-09-11T21:28:54Z",
  "published" : "2026-09-11T21:28:54Z",
  "aliases" : [ "CVE-2026-56828" ],
  "summary" : "Shopper: privilege escalation via improper Livewire admin component authorization",
  "details" : "## Summary\n\nThree 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).\n\nA 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.\n\nCVSS 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).\n\n## Vulnerable components (paths relative to repo root)\n\n### 1) `packages/admin/src/Livewire/Components/Settings/Team/Permissions.php`\n\n- `togglePermission(int $id)` at line 28 calls `$this->authorize('view_users');`\n- `removePermission(int $id)` at line 55 calls `$this->authorize('view_users');`\n\nThe 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.\n\nNet 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.\n\n### 2) `packages/admin/src/Livewire/SlideOvers/CreateTeamMember.php`\n\n- `mount()` at line 53 calls `$this->authorize('view_users');`\n- `store()` at line 122 calls `$this->authorize('view_users');`\n\nThis file is `new file mode 100755` in commit `fcd0c59` — it was created as part of the security fix and inherited the same misclassified gate.\n\n`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.\n\n### 3) `packages/admin/src/Livewire/Pages/Settings/Team/RolePermission.php`\n\n- `deleteAction` at lines 81-90: only gated by `->visible($this->role->can_be_removed)`, with no `->authorize()` chain.\n\nPage-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).\n\n## Self-confirmation in the project's own test suite\n\nThe following tests are green on master @ `fcd0c59` — they ARE the PoC:\n\n```\ntests/Admin/Livewire/Components/Settings/Team/PermissionsTest.php\n  line 14-16: `givePermissionTo('view_users')` only\n  line 36-45: \"can toggle permission to role\" — passes\n  line 74-85: \"can remove permission\" — passes\n\ntests/Admin/Livewire/SlideOvers/CreateTeamMemberTest.php\n  line 16-18: `givePermissionTo('view_users')` only\n  line 29-56: \"can create new team member\" — passes, asserts the new user `hasRole('manager')`\n```\n\nA `view_users`-only Livewire user actor successfully toggles permissions, removes permissions, and creates a new privileged user — verified by Shopper's own regression tests.\n\n## Suggested fix\n\nChange `$this->authorize('view_users')` to `$this->authorize('access_setting')` in:\n\n- `Permissions::togglePermission`\n- `Permissions::removePermission`\n- `Permissions::mount` (defence in depth, matches `Team\\Index`)\n- `CreateTeamMember::mount`\n- `CreateTeamMember::store`\n\nAdd `->authorize('access_setting')` to `RolePermission::deleteAction` (matches the pattern already applied to `generatePermissionsAction`, `createPermissionAction`, and `Team\\Index::DeleteAction`).\n\nUpdate the two regression tests to use `access_setting` instead of `view_users` so they accurately reflect the privilege boundary.\n\n## Resources\n\n- Prior advisory of the same class: https://github.com/shopperlabs/shopper/security/advisories/GHSA-f946-9qp6-vgch\n- Fix commit that introduced these residual gaps: https://github.com/shopperlabs/shopper/commit/fcd0c5920588702df5b874f432b1042abd77a50b\n- CWE-285 Improper Authorization\n- CWE-862 Missing Authorization\n\n### Credits\n\nReported by Vishal Shukla(@shukla304) using sechub.dev AI Agent\n\n### Support\n\nIf this disclosure was useful and if users would like to support continued open-source security research and responsible-disclosure work, they can sponsor at https://github.com/sponsors/therawdev — Shoppers thanks those who keeping open source safe.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "shopper/framework"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.8.0"
      }, {
        "fixed" : "2.9.2"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/shopperlabs/shopper/security/advisories/GHSA-j328-xmgp-j4q3"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/shopperlabs/shopper"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-285", "CWE-862" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-09-11T21:28:54Z",
    "nvd_published_at" : null
  }
}