CVE-2026-100371 InvoicePlane 权限绕过漏洞
影响次级管理员可接管主管理员账户
InvoicePlane 1.7.2 中,此前针对 Users::change_password() 的授权修复仅保护了直接改密操作,未保护密码找回所信任的 user_email 属性。次级管理员可先篡改主管理员的邮箱,再通过公开的密码找回流程获取重置令牌,从而完全接管 user_id=1 的主管理员账户。
影响范围
InvoicePlane 1.7.2 受影响,官方已通过提交 8616fa4 修复,具体修复版本号暂无公开信息。
漏洞详情
漏洞属于对象级授权缺失(越权)。Users::form() 在编辑主管理员账户时未做等价的授权校验,且 user_email 未被列入 PROTECTED_FIELDS,因此次级管理员(user_type=1 且 user_id != 1)可修改主管理员的邮箱地址。随后攻击者触发公开的密码找回流程,该流程按 user_email 定位账户,重置令牌便发送到攻击者控制的邮箱,最终实现账户接管。
利用条件与风险
利用前提是攻击者已拥有一个次级管理员账户,属于权限提升/横向越权场景,实战中可导致主管理员账户被完全接管,风险较高。
修复建议
官方已通过提交 8616fa4 修复,建议升级到包含该提交的版本;临时缓解措施暂无公开信息,可考虑限制次级管理员账户的创建与使用。
InvoicePlane is a self-hosted open source application for managing invoices, clients, and payments. In version 1.7.2, an authorization guard to Users::change_password(), was added to address a previous authorization flaw that allowed a secondary administrator (user_type=1, user_id != 1) to directly change the password of the primary administrator (user_id=1) through users/change_password/{id}. That remediation, however, protects only the direct password-change operation. It does not protect the identity attribute that password recovery actually trusts: user_email. Users::form() applies no equivalent object-level authorization check when editing the primary administrator’s account, and user_email is not included in PROTECTED_FIELDS. A secondary administrator can therefore rewrite the primary administrator’s email address, then drive the public password-recovery flow — which resolves the account by user_email — to receive the reset token and take over user_id=1. The result is an alternate attack path that achieves the same impact PR #1638 was intended to prevent: cross-administrator full account takeover of the primary administrator. This issue has been patched via commit 8616fa4.