Overview

six cves in one open-source e-commerce project

May 22, 2026
5 min read

TL;DR

I recently got six CVEs in Shopper, an open-source e-commerce platform built on Laravel.

The useful part was the spread. It was not one bug pattern repeated six times.

In the same codebase, I ended up with:

  • authorization bypasses
  • RBAC privilege escalation
  • discount race conditions
  • IDOR
  • sensitive data disclosure
  • stored XSS

All six were fixed in 2.8.0, so the affected range is basically everything before 2.8.0.

The six CVEs

CVESeveritySummary
CVE-2026-47740HighMissing authorization on order mutation actions in the admin panel allowed low-privilege authenticated users to mutate order state without the required write permissions.
CVE-2026-47741ModerateA discount race condition allowed silent over-redemption under concurrent checkout pressure, and the per-user usage limit logic was effectively bypassed.
CVE-2026-47742ModerateProduct editor sub-form Livewire components accepted unauthorized store() actions, so authenticated panel users could modify product data without the required permission.
CVE-2026-47744CriticalTeam settings contained authorization defects that let authenticated panel users take over the RBAC system itself.
CVE-2026-47745ModeratePayment methods, currencies, and carriers exposed inline toggles and record actions without proper per-action authorization checks.
CVE-2026-47743HighMultiple admin Livewire issues led to data tampering, sensitive data disclosure, and stored XSS.

CVE-2026-47744

This was the standout one for me.

It was not just “one missing check.” It was a team settings issue that let an authenticated panel user get into RBAC territory they were never supposed to control.

According to the advisory, the two main problems were:

  • Settings/Team/Index missing mount() authorization
  • Settings/Team/RolePermission using a read-only permission to guard write actions

Once I saw that, it was obvious this was not just another admin panel auth bug. If you can mess with team permissions, you are not attacking one feature anymore. You are attacking the permission model itself.

The technical core of that one was easy to summarize:

Settings/Team/Index::mount()
Settings/Team/RolePermission
view_users
manage_users

One page skipped the mount-time authorization entirely, and the other one guarded write actions with the wrong permission.

CVE-2026-47741

This one was fun for a different reason.

It was a race condition on discount usage limits, not a simple access control miss.

The kind of bug that is easy to underestimate, because the app still “looks fine” in normal usage. But once you think about concurrent checkout pressure, the whole thing changes. A merchant can silently over-accept discounted orders even though the configured usage_limit says otherwise.

There was also a related problem around per-user limits not being counted the way the validation logic expected. So it was not just a race, it was also bad accounting.

There is no flashy exploit chain here. It is broken business logic with real money impact.

The advisory tied that one to the checkout path directly:

CreateOrderFromCartAction::execute
DiscountDetail.total_use
usage_limit
usage_limit_per_user

That is the kind of code path I always like to see in a writeup, because it makes the failure mode much more concrete than just saying “coupon race condition.”

CVE-2026-47743

This one bundled three bug classes together:

  • IDOR via unlocked Livewire properties
  • plaintext password exposure through a hidden field flow
  • stored XSS on product barcode

That is a pretty good example of why I keep an eye on Livewire-heavy admin panels. Once a component starts trusting client-controlled state too much, weird things happen fast.

The stored XSS part was especially nice because it was not buried in some exotic sink. It was sitting on product barcode rendering.

The vulnerable pieces the advisory called out were:

#[Locked]
Customers/Create::store()
DNS1DFacade::getBarcodeHTML()
{!! !!}

That bundle is useful because it shows the three separate bug classes without needing to dump the entire component code.

The rest of the set

The other three CVEs were less dramatic individually, but together they painted a very clear picture:

  • CVE-2026-47740 showed missing authorization on order mutation actions
  • CVE-2026-47742 showed the same kind of trust problem on product editor sub-forms
  • CVE-2026-47745 showed per-action authorization gaps on payment methods, currencies, and carriers

So the pattern was not isolated. It repeated across different admin workflows.

The advisory pages were still specific enough to leave a technical breadcrumb trail:

cancel, markPaid, markComplete, capturePayment
->visible()
->authorize()
store()
edit_products
edit_payment_methods
edit_currencies
edit_carriers

So even in the “simpler” bugs, you could still see the same repeated smell: action methods and component handlers were present, but the real per-action permission gate was missing or too weak.

That is usually what makes a target really satisfying to audit: not just one lucky bug, but a repeated failure pattern.

The pattern across the set

This was not six copies of the same bug. It was:

  • access control failures
  • privilege escalation
  • race condition logic bugs
  • component state abuse
  • data exposure
  • XSS

That is the kind of set that makes a target memorable.

Fixed version

All six advisories were patched in 2.8.0.

So if you are just tracking the affected line for writeup purposes, the clean boundary is:

  • affected: versions before 2.8.0
  • patched: 2.8.0

CVE mapping