CVE-2026-56826
Shopper: Missing function-level authorization on Settings tax/zone/shipping Livewire components allows a low-privileged user to delete commerce configuration
Shopper is a Headless e-commerce Admin Panel. From 2.0.0 until 2.9.2, authenticated users who could reach the Settings pages with only access_setting could directly invoke destructive actions through the Livewire endpoint because packages/admin/src/Livewire/Components/Settings/Zones/ZoneShippingOptions.php, packages/admin/src/Livewire/Components/Settings/Zones/Detail.php, packages/admin/src/Livewire/Components/Settings/Taxes/Detail.php, and packages/admin/src/Livewire/Components/Settings/Taxes/TaxRates.php did not enforce server-side delete authorization. The actions could delete carrier options, shipping zones, tax zones, and tax rates, disrupting checkout shipping, payment-method mapping, and tax calculation. This issue is fixed in version 2.9.2.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
5.4
Shopper: Missing function-level authorization on Settings tax/zone/shipping Livewire components allows a low-privileged user to delete commerce configuration
Shopper is a Headless e-commerce Admin Panel. From 2.0.0 until 2.9.2, authenticated users who could reach the Settings pages with only access_setting could directly invoke destructive actions through the Livewire endpoint because packages/admin/src/Livewire/Components/Settings/Zones/ZoneShippingOptions.php, packages/admin/src/Livewire/Components/Settings/Zones/Detail.php, packages/admin/src/Livewire/Components/Settings/Taxes/Detail.php, and packages/admin/src/Livewire/Components/Settings/Taxes/TaxRates.php did not enforce server-side delete authorization. The actions could delete carrier options, shipping zones, tax zones, and tax rates, disrupting checkout shipping, payment-method mapping, and tax calculation. This issue is fixed in version 2.9.2.
- Record
CVE-2026-56826- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
EUVDEUVD-2026-100520
5.4
Shopper is a Headless e-commerce Admin Panel. From 2.0.0 until 2.9.2, authenticated users who could reach the Settings pages with only access_setting could directly invoke destructive actions through the Livewire endpoint because packages/admin/src/Livewire/Components/Settings/Zones/ZoneShippingOptions.php, packages/admin/src/Livewire/Components/Settings/Zones/Detail.php, packages/admin/src/Livewire/Components/Settings/Taxes/Detail.php, and packages/admin/src/Livewire/Components/Settings/Taxes/TaxRates.php did not enforce server-side delete authorization. The actions could delete carrier options, shipping zones, tax zones, and tax rates, disrupting checkout shipping, payment-method mapping, and tax calculation. This issue is fixed in version 2.9.2.
- Record
EUVD-2026-100520- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-f7h9-qv4x-9x57
5.4
Shopping privilege escalation through missing authorization in Settings components
Summary
Four Livewire components in the Settings area expose destructive Filament actions (delete / edit) that perform no server-side authorization. Any authenticated user who can reach the Settings pages — i.e. holding only the coarse access_setting permission, without being an admin and without any delete_*/edit_* permission — can delete tax zones, tax rates, shipping zones, and carrier (shipping-rate) options by invoking the component action directly over the Livewire endpoint.
These records sit on the storefront checkout path, so deleting them breaks shipping-rate calculation, removes region-scoped payment methods, and corrupts tax resolution at checkout.
This is inconsistent with the rest of the admin, where destructive actions are gated by granular permissions (e.g. Settings/Locations/Index uses ->authorize('delete_inventories'), and Order/Detail gates mutating actions with edit_orders).
Affected components
| Component | File | Unauthorized action |
|---|---|---|
| Settings\Zones\ZoneShippingOptions | packages/admin/src/Livewire/Components/Settings/Zones/ZoneShippingOptions.php:47 | delete → CarrierOption::query()->find($arguments['id'])->delete() (id is client-supplied) |
| Settings\Zones\Detail | packages/admin/src/Livewire/Components/Settings/Zones/Detail.php:46 | delete → DeleteAction on the bound Zone |
| Settings\Taxes\Detail | packages/admin/src/Livewire/Components/Settings/Taxes/Detail.php:42 | delete → DeleteAction on the bound TaxZone |
| Settings\Taxes\TaxRates | packages/admin/src/Livewire/Components/Settings/Taxes/TaxRates.php:97 | delete → DeleteAction on a TaxRate |
Each file contains zero authorize calls, and the actions declare neither ->authorize() nor an enforced ->visible() guard.
Details
The Settings pages mount these as child Livewire components. The parent page authorizes access_setting (e.g. Pages/Settings/Taxes.php:29), but the child components do not re-check authorization, and their destructive actions carry no ->authorize(). Because each Livewire component handles its own /livewire/update requests, the action executes purely on the page-level access_setting gate — there is no per-resource permission, and delete_zones / delete_taxes permissions are never even generated by the seeder (packages/admin/database/seeders/PermissionsTableSeeder.php).
ZoneShippingOptions::deleteAction() is the clearest case — it deletes by an id taken straight from the client action arguments with no scoping and no permission check:
// packages/admin/src/Livewire/Components/Settings/Zones/ZoneShippingOptions.php
public function deleteAction(): Action
{
return Action::make('delete')
->requiresConfirmation()
// ... no ->authorize(), no ->visible()
->action(function (array $arguments): void {
CarrierOption::query()->find($arguments['id'])->delete(); // client-controlled id
// ...
});
}
Proof of Concept
Confirmed with the project's own test harness (Pest + Orchestra Testbench, SQLite) — the real Livewire/Filament code path, executed as a non-admin user holding only access_setting.
use Livewire\Livewire;
use Shopper\Core\Models\{CarrierOption, Zone};
use Shopper\Livewire\Components\Settings\Zones\ZoneShippingOptions;
use Tests\Core\Stubs\User;
uses(Tests\Admin\TestCase::class);
it('low-priv access_setting user deletes a CarrierOption with no authorization', function (): void {
$attacker = User::factory()->create();
$attacker->givePermissionTo('access_setting'); // NOT admin, NO delete_* permission
$this->actingAs($attacker, config('shopper.auth.guard'));
$zone = Zone::factory()->create();
$option = CarrierOption::factory()->create(['zone_id' => $zone->id]);
Livewire::test(ZoneShippingOptions::class, ['selectedZoneId' => $zone->id])
->callAction('delete',…
- Record
GHSA-f7h9-qv4x-9x57- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
NVD
5.4
Shopper is a Headless e-commerce Admin Panel. From 2.0.0 until 2.9.2, authenticated users who could reach the Settings pages with only access_setting could directly invoke destructive actions through the Livewire endpoint because packages/admin/src/Livewire/Components/Settings/Zones/ZoneShippingOptions.php, packages/admin/src/Livewire/Components/Settings/Zones/Detail.php, packages/admin/src/Livewire/Components/Settings/Taxes/Detail.php, and packages/admin/src/Livewire/Components/Settings/Taxes/TaxRates.php did not enforce server-side delete authorization. The actions could delete carrier options, shipping zones, tax zones, and tax rates, disrupting checkout shipping, payment-method mapping, and tax calculation. This issue is fixed in version 2.9.2.
- Record
CVE-2026-56826- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
OSV
5.4
Shopper: Missing function-level authorization on Settings tax/zone/shipping Livewire components allows a low-privileged user to delete commerce configuration
Shopper is a Headless e-commerce Admin Panel. From 2.0.0 until 2.9.2, authenticated users who could reach the Settings pages with only access_setting could directly invoke destructive actions through the Livewire endpoint because packages/admin/src/Livewire/Components/Settings/Zones/ZoneShippingOptions.php, packages/admin/src/Livewire/Components/Settings/Zones/Detail.php, packages/admin/src/Livewire/Components/Settings/Taxes/Detail.php, and packages/admin/src/Livewire/Components/Settings/Taxes/TaxRates.php did not enforce server-side delete authorization. The actions could delete carrier options, shipping zones, tax zones, and tax rates, disrupting checkout shipping, payment-method mapping, and tax calculation. This issue is fixed in version 2.9.2.
- Record
CVE-2026-56826- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
OSVGHSA-f7h9-qv4x-9x57
5.4
Shopping privilege escalation through missing authorization in Settings components
Summary
Four Livewire components in the Settings area expose destructive Filament actions (delete / edit) that perform no server-side authorization. Any authenticated user who can reach the Settings pages — i.e. holding only the coarse access_setting permission, without being an admin and without any delete_*/edit_* permission — can delete tax zones, tax rates, shipping zones, and carrier (shipping-rate) options by invoking the component action directly over the Livewire endpoint.
These records sit on the storefront checkout path, so deleting them breaks shipping-rate calculation, removes region-scoped payment methods, and corrupts tax resolution at checkout.
This is inconsistent with the rest of the admin, where destructive actions are gated by granular permissions (e.g. Settings/Locations/Index uses ->authorize('delete_inventories'), and Order/Detail gates mutating actions with edit_orders).
Affected components
| Component | File | Unauthorized action |
|---|---|---|
| Settings\Zones\ZoneShippingOptions | packages/admin/src/Livewire/Components/Settings/Zones/ZoneShippingOptions.php:47 | delete → CarrierOption::query()->find($arguments['id'])->delete() (id is client-supplied) |
| Settings\Zones\Detail | packages/admin/src/Livewire/Components/Settings/Zones/Detail.php:46 | delete → DeleteAction on the bound Zone |
| Settings\Taxes\Detail | packages/admin/src/Livewire/Components/Settings/Taxes/Detail.php:42 | delete → DeleteAction on the bound TaxZone |
| Settings\Taxes\TaxRates | packages/admin/src/Livewire/Components/Settings/Taxes/TaxRates.php:97 | delete → DeleteAction on a TaxRate |
Each file contains zero authorize calls, and the actions declare neither ->authorize() nor an enforced ->visible() guard.
Details
The Settings pages mount these as child Livewire components. The parent page authorizes access_setting (e.g. Pages/Settings/Taxes.php:29), but the child components do not re-check authorization, and their destructive actions carry no ->authorize(). Because each Livewire component handles its own /livewire/update requests, the action executes purely on the page-level access_setting gate — there is no per-resource permission, and delete_zones / delete_taxes permissions are never even generated by the seeder (packages/admin/database/seeders/PermissionsTableSeeder.php).
ZoneShippingOptions::deleteAction() is the clearest case — it deletes by an id taken straight from the client action arguments with no scoping and no permission check:
// packages/admin/src/Livewire/Components/Settings/Zones/ZoneShippingOptions.php
public function deleteAction(): Action
{
return Action::make('delete')
->requiresConfirmation()
// ... no ->authorize(), no ->visible()
->action(function (array $arguments): void {
CarrierOption::query()->find($arguments['id'])->delete(); // client-controlled id
// ...
});
}
Proof of Concept
Confirmed with the project's own test harness (Pest + Orchestra Testbench, SQLite) — the real Livewire/Filament code path, executed as a non-admin user holding only access_setting.
use Livewire\Livewire;
use Shopper\Core\Models\{CarrierOption, Zone};
use Shopper\Livewire\Components\Settings\Zones\ZoneShippingOptions;
use Tests\Core\Stubs\User;
uses(Tests\Admin\TestCase::class);
it('low-priv access_setting user deletes a CarrierOption with no authorization', function (): void {
$attacker = User::factory()->create();
$attacker->givePermissionTo('access_setting'); // NOT admin, NO delete_* permission
$this->actingAs($attacker, config('shopper.auth.guard'));
$zone = Zone::factory()->create();
$option = CarrierOption::factory()->create(['zone_id' => $zone->id]);
Livewire::test(ZoneShippingOptions::class, ['selectedZoneId' => $zone->id])
->callAction('delete',…
- Record
GHSA-f7h9-qv4x-9x57- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
shopper/frameworkPackagist |
2.0.0 up to 2.9.2 | 2.9.2 |
shopper/frameworkPackagist |
2.0.0 up to 2.9.2, plus listed versions v2.0.0v2.0.1v2.0.2v2.0.3v2.1.1 Show 36 moreShow lessv2.1.2v2.1.3v2.1.4v2.1.5v2.1.6v2.2v2.2.1v2.2.2v2.2.3v2.2.4v2.2.5v2.2.6v2.2.7v2.3v2.3.1v2.3.2v2.3.3v2.4.0v2.4.1v2.4.2v2.4.3v2.5.0v2.5.1v2.6.0v2.6.1v2.6.2v2.6.3v2.6.4v2.7.0v2.7.1v2.7.2v2.7.3v2.8.0v2.8.1v2.9.0v2.9.1 |
2.9.2 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-56826 is a medium vulnerability (CVSS 5.4) in Shopperdotcom Shopper, published September 11, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.34%, the 27th percentile. Fixed in shopper/framework 2.9.2.
References
github.com/shopperlabs/shopper/security/advisories/GHSA-f7h9-qv4x-9x57
github.com/shopperlabs/shopper/pull/570
github.com/shopperlabs/shopper/commit/bf72e2753e21296184596d507336c7d65ecd46ff
github.com/shopperlabs/shopper/releases/tag/v2.9.2
github.com/advisories/GHSA-f7h9-qv4x-9x57
github.com/CVEProject/cvelistV5/tree/main/cves/2026/56xxx/CVE-2026-56826.json
nvd.nist.gov/vuln/detail/CVE-2026-56826
github.com/shopperlabs/shopper
Left out here: the rest of 2 source descriptions. The JSON record has them.