Kimdir01/econumo-multi-vuln-cve

GitHub: Kimdir01/econumo-multi-vuln-cve

针对 Econumo 个人理财应用的安全漏洞披露项目,记录了硬编码密钥、权限提升、弱加密等 6 个主要漏洞的 PoC 与修复建议。

Stars: 0 | Forks: 0

# GitHub 安全公告:Econumo — 硬编码 JWT 私钥、权限提升、弱加密、无 CSRF ## 公告信息 | 字段 | 值 | |-------|-------| | **严重程度** | 严重 / 高 | | **CWE** | CWE-798 (硬编码加密密钥) / CWE-269 (权限提升) / CWE-916 (弱密码哈希) / CWE-352 (CSRF) | | **CVSS v3.1** | 9.8 (硬编码 JWT 密钥) / 8.1 (权限提升) / 8.8 (无 CSRF) / 7.4 (弱哈希) | | **CVSS 向量** | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H | ## 摘要 Econumo(基于 Symfony 5.4 的个人理财/预算应用程序)包含严重漏洞:(1) 代码库中硬编码了 JWT 私钥,导致可为任何用户伪造 token,(2) 损坏的 `canShareBudget()` 逻辑导致权限提升——任何用户无论角色如何均可共享预算,(3) 密码哈希仅使用 500 次迭代的 SHA-512(OWASP 建议 600,000+ 次),(4) 所有 50 多个表单全局禁用 CSRF,(5) “自动连接所有用户”功能将财务数据暴露给所有注册用户。 ## 漏洞详情 ### 受影响包/代码库 - **代码库:** Econumo - **受影响版本:** 当前版本 - **已修补版本:** 无 (0-day) **审计提交哈希:** `371a4b2352d7fa4ed114cd58078bce6a3ae98517` ## CVE-REQUEST-001:代码库中硬编码 JWT 私钥 (CVSS 9.8) **文件:** `config/jwt/private.pem` 代码库中提交了一个私有的 RSA 密钥——用于 JWT token 签名: ``` config/jwt/private.pem config/jwt/public.pem ``` **任何有权访问该公开代码库的人都可以为任何用户伪造有效的 JWT token。** JWT token 具有 30 天的 TTL。由于没有 token 吊销机制,伪造的 token 将提供长达 30 天的完整访问权限。 **PoC:** ``` import jwt, datetime with open('config/jwt/private.pem', 'r') as f: private_key = f.read() token = jwt.encode({ 'sub': 'admin@econumo.local', 'iat': datetime.datetime.utcnow(), 'exp': datetime.datetime.utcnow() + datetime.timedelta(days=30) }, private_key, algorithm='RS256') # 使用 token 以 admin 身份访问任何 API ``` ## CVE-REQUEST-002:因 `canShareBudget()` 逻辑损坏导致的权限提升 (CVSS 8.1) **文件:** `src/EconumoBundle/Domain/Service/Budget/BudgetAccessService.php`,第 110-122 行 ``` public function canShareBudget(Id $userId, Id $budgetId): bool { try { $role = $this->getBudgetRole($userId, $budgetId); if ($role->isOwner() || $role->isAdmin()) { return true; } } catch (AccessDeniedException) { return false; } return true; // BUG: Falls through to TRUE for non-owner/non-admin! } ``` 任何具有任何级别预算访问权限的用户(甚至是“读者”)都可以与任意用户共享该预算。该函数对所有非所有者/非管理员角色返回 `true`,而不是 `false`。 ## CVE-REQUEST-003:弱密码哈希 (SHA-512 / 500 次迭代) (CVSS 7.4) **文件:** `config/packages/security.yaml`,第 3-6 行 ``` password_hashers: App\EconumoBundle\Domain\Entity\User: algorithm: sha512 encode_as_base64: true iterations: 500 # OWASP recommends 600,000+ for PBKDF2! ``` 仅有 500 次迭代的 SHA-512 是极其不足的。商用 GPU 每秒可以测试数百万个密码。结合无密码强度策略(无最小长度、无复杂性要求)以及硬编码的 JWT 密钥,数据库泄露将导致离线密码被快速破解。 ## CVE-REQUEST-004:无 CSRF 保护——所有表单均禁用 CSRF (CVSS 8.8) **在所有 50 多个表单类中的模式:** ``` $resolver->setDefaults(['csrf_protection' => false]); ``` `src/EconumoBundle/UI/Controller/Api/*/Validation/*Form.php` 下的每一个表单类都明确禁用了 CSRF。受影响的操作包括: - 创建/修改/删除交易 - 创建/修改/删除预算和预算限额 - 创建/修改/删除账户 - 创建/修改/删除分类 - 共享预算 / 授予访问权限 - 修改收款人 - 吊销用户访问权限 **PoC:** ```
``` ## CVE-REQUEST-005:自动连接所有用户功能 (CVSS 7.5) **文件:** `src/EconumoBundle/Application/UseCase/ConnectUsers/ConnectUsersEventHandler.php` 当 `ECONUMO_CONNECT_USERS=true` 时,每个新注册的用户都会自动连接到所有现有用户。由于连接会启用账户共享和预算访问,这会将所有财务数据暴露给每个注册者。 ## CVE-REQUEST-006:生产环境错误响应中的堆栈跟踪 (CVSS 5.3) **文件:** `src/EconumoBundle/UI/Service/Response/ResponseFactory.php`,第 54-56 行 ``` if ($exception instanceof Throwable) { $data['exceptionType'] = $exception::class; $data['stackTrace'] = $exception->getTrace(); } ``` JSON 错误响应中暴露了完整的堆栈跟踪,包含文件路径、类名和方法签名。 ## 其他发现(共 17 项): | # | 漏洞 | CVSS | 类型 | |---|--------------|------|------| | 3 | JWT token 30 天 TTL(无刷新机制) | 6.5 | Session Mgmt | | 4 | 通过密码重置进行用户枚举 | 5.3 | Enumeration | | 9 | 认证 endpoint 上无速率限制 | 5.3 | Brute Force | | 11 | 无密码强度验证 | 5.9 | Weak Policy | | 12 | 用户名无输入验证 | 4.3 | XSS Risk | | 13 | CORS 可能使用通配符(可配置) | 6.1 | CORS | | 14 | 系统 API token 存在时序攻击风险 | 3.1 | Side-Channel | | 15 | 分类替换 ID 存在跨用户风险 | 5.4 | IDOR | | 16 | CSV 导入在未经验证下创建实体 | 4.3 | Resource Exhaustion | | 17 | 错误响应中包含异常类名 | 3.3 | Info Disclosure | ## 影响 - 通过伪造 JWT 密钥实现**完全账户接管** - 通过权限提升导致**财务数据泄露**(任何读者 -> 管理员) - 通过弱哈希导致**密码被破解**(GPU 上每秒数百万次) - 通过对所有交易的 CSRF 实施跨域**财务欺诈** - 通过自动连接向所有用户暴露数据而造成**隐私违规** - 通过堆栈跟踪导致**内部代码结构泄露** ## 补丁 / 修复 1. **立即执行:** 从代码库中移除 `config/jwt/private.pem`;为每次部署生成独立的密钥 2. 修复 `canShareBudget()` —— 将最后的 `return true` 更改为 `return false` 3. 用 bcrypt 或 argon2id 替换 SHA-512:`algorithm: bcrypt`, `cost: 12` 4. 启用 CSRF 保护:从所有表单中移除 `'csrf_protection' => false` 5. 默认禁用 `ECONUMO_CONNECT_USERS` 6. 将 JWT TTL 减少至 15-60 分钟,并实现 refresh token 7. 在认证 endpoint 添加速率限制 8. 添加最小密码长度(12+ 个字符)和复杂性要求 9. 从生产环境的错误响应中移除堆栈跟踪 10. 为系统 API token 添加常数时间比较 ## 披露时间表 - **2026-06-28:** 由 Fatullayev Asadbek (Kimdir01) 发现所有漏洞 - **待定:** 报告给维护者 - **待定:** 通过 GitHub 请求 CVE - **待定:** 发布公告 ## 致谢 - 发现者:Fatullayev Asadbek | GitHub:Kimdir01 - 独立安全研究员 ## 参考 - CWE-798:使用硬编码凭证 (Cryptographic Key) - CWE-269:权限管理不当 - CWE-916:使用计算量不足的密码哈希 - CWE-352:跨站请求伪造
标签:JWT, PoC, Web安全, 协议分析, 暴力破解, 权限提升, 漏洞披露, 蓝队分析, 逆向工具