Nixon-H/CVE-2025-68147-OSPOS-Stored-XSS
GitHub: Nixon-H/CVE-2025-68147-OSPOS-Stored-XSS
CVE-2025-68147 的 PoC 仓库,演示了 OpenSourcePOS 店铺配置模块中的存储型 XSS 漏洞及其利用方式与修复方案。
Stars: 2 | Forks: 1
# CVE-2025-68147:OpenSourcePOS 中的存储型跨站脚本攻击 (XSS)
| 元数据 | 详情 |
| --- | --- |
| **CVE ID** | **[CVE-2025-68147](https://cve.mitre.org/cgi-bin/cvename.cgi%3Fname%3DCVE-2025-68147)** |
| **严重程度** | **高** `CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:N` |
| **漏洞类型** | 存储型跨站脚本攻击 (CWE-79) |
| **受影响版本** | OpenSourcePOS v3.4.0, v3.4.1 |
| **已修复版本** | **v3.4.2** |
| **受影响组件** | 店铺配置模块 (`Return Policy` 字段) |
| **报告者** | [Aditya Singh (Nixon-H)](https://github.com/Nixon-H) |
## 📝 摘要
在 OpenSourcePOS 的 **店铺配置** 模块中发现了一个 **存储型跨站脚本攻击 (XSS)** 漏洞。应用程序在将用户提供的“Return Policy”字段输入存储到 `ospos_app_config` 数据库表中之前,未能对其进行妥善的清理。
该缺陷允许拥有配置权限的已认证攻击者(或利用了单独 CSRF 攻击链的攻击者)注入任意的 JavaScript payload。由于“Return Policy”会在每张销售收据上动态渲染,因此每当生成或查看收据时,注入的 payload 就会在**任何用户**(包括低权限的收银员、其他管理员或顾客)的浏览器中自动执行。
## 🕵️♂️ 技术根本原因分析
### 1. 漏洞逻辑
该漏洞存在于收据视图模板中:`app/Views/sales/receipt_default.php`。
应用程序从全局配置数组(`$this->config['return_policy']`)中获取“Return Policy”字符串,并将其准备用于显示。
* **错误所在:** 开发人员使用了原生的 PHP 函数 `nl2br()` 将换行符转换为 HTML 换行符(`
`)。 * **失败之处:** `nl2br()` **不会清理** HTML 特殊字符。它将 `` 由于控制器端(`Config.php`)没有进行输入清理,且视图端(`receipt_default.php`)没有进行输出转义,因此该应用程序容易受到存储型 XSS 的攻击。 ## 💥 概念验证 (PoC) ### 攻击向量 该攻击针对的是 **店铺配置** 面板,但会影响到 **销售/收据** 模块。 1. **入口点:** `http://[TARGET]/config`(用于保存配置的 POST 请求) 2. **执行点:** `http://[TARGET]/sales/receipt/[SALE_ID]` ### 逐步利用过程 **第一步:注入** 我们以管理员身份登录,并导航至 **店铺配置** -> **通用**。在 **“Return Policy”** 文本区域中,我们注入了以下特定的 payload: ``` Standard Return Policy: No Refunds. ``` **第二步:持久化** 点击“提交”后,应用程序向 `/config/save` 发送了一个 POST 请求。payload 被成功提交到了数据库中。 **第三步:触发** 为了验证对其他用户的影响: 1. 我们登出并以**收银员**(低权限账户)的身份重新登录。 2. 我们导航至 **销售** 模块。 3. 我们将一件测试商品加入购物车并点击了 **“完成销售”**。 4. **结果:** 应用程序重定向到收据视图(例如 `http://localhost/sales/receipt/1`)。浏览器解析了 `return_policy` div,遇到 `
`)。 * **失败之处:** `nl2br()` **不会清理** HTML 特殊字符。它将 `` 由于控制器端(`Config.php`)没有进行输入清理,且视图端(`receipt_default.php`)没有进行输出转义,因此该应用程序容易受到存储型 XSS 的攻击。 ## 💥 概念验证 (PoC) ### 攻击向量 该攻击针对的是 **店铺配置** 面板,但会影响到 **销售/收据** 模块。 1. **入口点:** `http://[TARGET]/config`(用于保存配置的 POST 请求) 2. **执行点:** `http://[TARGET]/sales/receipt/[SALE_ID]` ### 逐步利用过程 **第一步:注入** 我们以管理员身份登录,并导航至 **店铺配置** -> **通用**。在 **“Return Policy”** 文本区域中,我们注入了以下特定的 payload: ``` Standard Return Policy: No Refunds. ``` **第二步:持久化** 点击“提交”后,应用程序向 `/config/save` 发送了一个 POST 请求。payload 被成功提交到了数据库中。 **第三步:触发** 为了验证对其他用户的影响: 1. 我们登出并以**收银员**(低权限账户)的身份重新登录。 2. 我们导航至 **销售** 模块。 3. 我们将一件测试商品加入购物车并点击了 **“完成销售”**。 4. **结果:** 应用程序重定向到收据视图(例如 `http://localhost/sales/receipt/1`)。浏览器解析了 `return_policy` div,遇到 `