Jun 6, 2026·5 min read·6 visits
Low-privileged Shopper admin panel users can manipulate Livewire payloads to edit any product's pricing, inventory, SEO, and assets because mutating endpoints lacked authorization checks and model IDs were not locked.
An authorization bypass and client-side property tampering vulnerability (CVE-2026-47742) in the Shopper headless admin panel (built on Laravel and Livewire) allows low-privileged users to modify arbitrary product records (Insecure Direct Object Reference). This occurs due to unlocked public model properties and a complete lack of access control checks on mutating sub-form store methods.
Shopper is an open-source headless e-commerce admin panel constructed on the Laravel framework and powered by Livewire components. The core management interface exposes various sub-forms within the product editor to permit administrative actions. These sub-forms cover key operational details, including pricing, SEO settings, shipping measurements, asset files, and inventory control.\n\nThe exposure is centered on the administrative backend panel, specifically targeting the asynchronous endpoints utilized by the Livewire state synchronization engine. An attacker possessing authenticated access to the panel, even with restricted read-only permissions, can target these components directly. This occurs because the sub-form components lack functional access control validation prior to processing state updates.\n\nThe vulnerability represents a combination of CWE-862 (Missing Authorization) and CWE-807 (Reliance on Untrusted Inputs in a Security Decision). This combination facilitates client-side tampering and direct object referencing, enabling low-privileged actors to bypass role-based access control (RBAC) boundaries. Successful exploitation leads to unauthorized modifications across the entire product catalog database.
The flaw lies within the state-management paradigm of Laravel Livewire v3. During the application's client-server communication lifecycle, component properties are serialized into a JSON state snapshot (dehydration) and passed to the frontend. Subsequent client interactions submit this snapshot back to the backend server to re-instantiate the stateful server-side component (hydration).\n\nIn vulnerable installations of Shopper, public database model properties, such as $product, were exposed directly to the client interface without locking constraints. Livewire serializes Eloquent models by encoding their database class name and primary key. Because these properties were not secured with the #[Locked] attribute, Livewire allowed the client payload to rewrite the model identifier (e.g., modifying the targeted ID from 42 to 999).\n\nDuring the hydration phase, the Livewire engine receives the tampered JSON, trusts the user-supplied primary key, and queries the database to bind the modified model instance. Crucially, the component's state-mutating store() method does not perform any server-side authorization checks. Consequently, the application executes the update operation against an arbitrary product record, bypassing both intended data boundaries (IDOR) and role-based access rules.
Examination of the vulnerable codebase reveals complete trust in the component's internal state during mutation requests. In packages/admin/src/Livewire/Components/Products/Form/Inventory.php, the original store() method updated the database without validation:\n\nphp\n// Vulnerable server-side component state\npublic Product $product;\n\npublic function store(): void\n{\n // No permission checks exist here\n $this->product->update($this->form->getState());\n $this->dispatch('product.updated');\n}\n\n\nThe patch applied in Commit fcd0c5920588702df5b874f432b1042abd77a50b introduces two defensive controls. First, the #[Locked] attribute is assigned to the public model property. This causes Livewire to sign the property on dehydration and verify the signature on hydration, preventing ID tampering. Second, explicit authorization is enforced inside the method body.\n\nphp\n// Patched state enforcement\nuse Livewire\\Attributes\\Locked;\n\n#[Locked]\npublic Product $product;\n\npublic function store(): void\n{\n // Enforce role-based access control explicitly\n $this->authorize('edit_products');\n\n $this->product->update($this->form->getState());\n $this->dispatch('product.updated');\n}\n\n\nThe remediation is robust and covers adjacent components, including Edit.php, Seo.php, Shipping.php, and Files.php. By combining cryptographic property signing via #[Locked] with explicit server-side RBAC validation, the application successfully prevents exploitation of this entire attack vector.
To execute the exploit, an attacker must first obtain a low-privileged authenticated session on the Shopper admin panel. This requirement is low complexity, as any standard staff account without write privileges is sufficient. No administrative permissions like edit_products are required.\n\nThe attacker locates a product modification sub-form to retrieve the initial Livewire component state structure. By capturing the underlying AJAX communication directed at the /livewire/message/{component-name} endpoint, the attacker extracts the dehydrated JSON state. This payload includes a memo block with the identifier of the product model being processed.\n\nThe attacker modifies the product.id field to reference a target record of their choosing. They append state updates containing arbitrary product information, such as adjusted unit pricing or manipulated stock volumes. Upon dispatching the mutated JSON snapshot via the intercepting proxy, the Livewire engine reconciles the state, binds the arbitrary model, and runs the store() method, committing the unauthorized changes.
The security impact is classified as High for integrity, with a CVSS v3.1 score of 6.5. Because the application processes transaction-critical records, unauthorized modifications can cause direct business disruption. An attacker can set pricing values to nominal amounts, deplete or artificially inflate inventory stock, or manipulate product SEO profiles to redirect web traffic.\n\nmermaid\ngraph LR\n Attacker["Low-Privilege Session"] -->|1. Manipulates JSON Payload| Livewire["Livewire Hydration Engine"]\n Livewire -->|2. Binds Arbitrary Model ID| DB[("Application Database")]\n Livewire -->|3. Invokes Unprotected store()| DB\n DB -->|4. Writes Tampered Price/Stock| DB\n\n\nFurthermore, because the Files sub-form is also vulnerable, an attacker could change media attachments and associated assets. This could lead to the distribution of malicious assets or defacement of the public storefront. The exploit's scope is restricted to the Shopper e-commerce application databases, leaving host operating systems and system availability unaffected.
Organizations must upgrade shopperlabs/shopper to version 2.8.0 or higher immediately to resolve the underlying vulnerability. This version incorporates the necessary Livewire attributes and authorization hooks to defend the product sub-forms. Update commands should be executed via Composer inside the application root directory.\n\nWhere an immediate upgrade to version 2.8.0 is prevented by operational dependencies, administrators should manually apply the security patch. This requires modifying the target sub-forms within packages/admin/src/Livewire/Components/Products/Form/ to introduce #[Locked] attributes and call $this->authorize('edit_products') inside the store routines.\n\nWeb Application Firewalls (WAFs) can be configured to detect or block manipulation patterns. WAF signatures should monitor asynchronous JSON payloads directed at Shopper's Livewire endpoints, searching for state updates containing mismatched product identifiers or anomalous transactional modifications triggered by unauthorized session tokens.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
shopper shopperlabs | < 2.8.0 | 2.8.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862, CWE-807 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 6.5 (Medium) |
| EPSS Score | 0.00029 (Percentile: 8.91%) |
| Exploit Status | PoC / Conceptual |
| CISA KEV Status | Not Listed |
TinyMCE versions 6.8.0 through 7.0.1 contain a high-severity Cross-Site Scripting (XSS) vulnerability. The flaw exists in the custom HTML parser and sanitizer module, which incorrectly manages SVG namespace scopes when parsing nested elements. A low-privileged or unauthenticated attacker can submit a crafted HTML payload containing nested SVG structures to bypass sanitization filters, leading to arbitrary JavaScript execution in the context of the victim's browser session.
CVE-2026-47759 is a critical stored Cross-Site Scripting (XSS) vulnerability affecting multiple active branches of the TinyMCE rich text editor. The flaw resides in the editor's handling of user-controlled, prefixed internal attributes, such as data-mce-href, data-mce-src, and data-mce-style. When processing raw HTML inputs, TinyMCE's internal validation schema neglects to inspect these custom prefixed attributes. During HTML serialization, the editor's engine extracts these unsanitized values and copies them back into standard executable attributes, overwriting any previously sanitized standard values and leading to execution of arbitrary code.
A high-severity stored Cross-Site Scripting (XSS) vulnerability was identified in the TinyMCE rich text editor. The flaw exists in the handling of the 'protect' configuration option, where forged placeholder comments containing malicious payloads bypass the editor's sanitization routines and execute arbitrary JavaScript during serialization and content restoration.
Shopper is an open-source headless e-commerce administration panel built on Laravel, Livewire, and Filament. Prior to version 2.8.0, the admin tables for PaymentMethods, Currencies, and Carriers exposed inline toggles and per-record actions that could be modified by any authenticated user without verifying the corresponding administrative permissions on the backend.
An Insecure Direct Object Reference (IDOR) vulnerability in Bugsink (versions < 2.2.0) allows authenticated users with access to at least one project to view sensitive event details (including stack traces, local/environment variables, and execution breadcrumbs) belonging to other projects, by supplying a known event UUID directly to the issue event URL paths.
Bugsink prior to version 2.2.0 is vulnerable to Broken Object Level Authorization (BOLA). The issue list view authorizes access based on the project in the URL path but applies requested bulk actions to submitted issue UUIDs globally, without verifying project ownership.