| 字段 | 详情 |
|---|---|
| CVE ID | CVE-2026-8794 |
| 产品 | PaperCut NG |
| 受影响版本 | 25.0.11(Build 75758)及更早版本 |
| CWE | CWE-208 — 可观察的时序差异 |
| CVSS 分数 | 3.7(低)— 单独使用时;与 CVE-2026-8793 链式利用时升级 |
| 研究人员 | Vivien LEBAS(@Hazaz) |
| 报告时间 | 2026 年 5 月 |
| 状态 | 已修复 — PaperCut NG 26.0.3 |
PaperCut NG 的认证端点在对已存在账户和不存在账户进行登录尝试时,表现出可测量的时序差异。这种差异源于仅在找到匹配账户时才执行 bcrypt 密码哈希运算,使得未认证的攻击者能够通过测量 HTTP 响应时间来可靠地判断系统中是否存在某个用户名。
当与 CVE-2026-8793(缺乏暴力破解防护)结合时,该漏洞可构成完整的凭据破解攻击链:先枚举有效用户名,再对目标执行无限制的密码猜测,且无需担心账户被锁定。
时序差异源于一种经典的实现模式:应用仅在数据库中找到与提交的用户名匹配的账户时才调用 bcrypt 比较。对于不存在的账户,认证例程在调用 bcrypt 之前就提前退出,导致响应时间明显更短。
Valid username: DB lookup (found) → bcrypt comparison → failure response ~2.1s avg
Invalid username: DB lookup (not found) → immediate failure response ~0.2s avg
该模式已有充分文档记载(参见 CWE-208)。标准的修复措施是即使账户不存在也执行一次虚拟的 bcrypt 比较,以均衡两条代码路径的响应时间。
在受控条件下,对 PaperCut NG 登录端点进行了认证尝试:
--write-out "%{time_total}" 的 curl,所有情况下均故意使用错误密码这两个分布呈现零重叠,即使在中等网络抖动下也能可靠地进行枚举。
# Measure response time for an existing account (wrong password)
curl -s -o /dev/null -w "%{time_total}\n" \
-X POST "http://<target>:9191/app" \
-H "Origin: http://<target>:9191" \
--data "service=direct/1/Home/%24Form&inputUsername=admin&inputPassword=wrongpassword"
# Output: ~2.1s
# Measure response time for a non-existent account
curl -s -o /dev/null -w "%{time_total}\n" \
-X POST "http://<target>:9191/app" \
-H "Origin: http://<target>:9191" \
--data "service=direct/1/Home/%24Form&inputUsername=zz_doesnotexist_zz&inputPassword=wrongpassword"
# Output: ~0.2s
响应时间显著高于约 0.5 秒,即可可靠地表明该用户名有效。通过一个简单脚本,即可针对常见企业命名模式(firstname.lastname、flastname 等)的字典自动执行枚举。
该发现在作为两阶段攻击的第一步时影响最大:
步骤 1(CVE-2026-8794,即本发现) — 通过测量认证响应时间来构建有效的 PaperCut NG 账户名列表。在企业环境中,根据公开来源(LinkedIn、公司网站、电子邮件签名)整理出的少量 firstname.lastname 组合字典通常就足够了。
步骤 2(CVE-2026-8793) — 对确认有效的账户提交无限制的密码尝试。由于缺乏速率限制或锁定机制,任何撞库或密码喷洒攻击都可以全程在线并以全速进行。
能够访问 TCP/9191 网络的未认证攻击者可以:
在典型的企业部署中,PaperCut 用户名与 Active Directory 账户一一对应。因此,确认有效的 PaperCut 用户名同时也是确认有效的域账户名,从而将侦察价值扩展到 PaperCut 本身之外。
对于管理员(临时缓解措施):
对于厂商:
当提交的用户名与任何账户都不匹配时,执行常量时间的虚拟 bcrypt 比较,确保无论账户是否存在,响应时间都保持均衡:
# Pseudocode — constant-time authentication pattern
user = db.find_user(username)
if user:
valid = bcrypt.verify(password, user.password_hash)
else:
bcrypt.verify(password, DUMMY_HASH) # always run, result discarded
valid = False
这是在认证流程中缓解 CWE-208 的成熟模式。
| 日期 | 事件 |
|---|---|
| 2026 年 5 月 9 日 | 初始报告提交给 PaperCut 安全团队 |
| 2026 年 5 月 10 日 | 已收到确认 |
| 2026 年 5 月 | CVE-2026-8794 由 PaperCut(CNA)分配 |
按照负责任的披露原则进行披露。完整的技术细节已在公开发布之前分享给 PaperCut 安全团队。
研究人员: Vivien LEBAS — @Hazaz
| 条件 | 最小值(秒) | 最大值(秒) | 平均值(秒) | 标准差 |
|---|
已存在账户(admin) | 2.08 | 2.19 | 2.13 | 0.031 |
不存在账户(zz_doesnotexist_zz) | 0.18 | 0.24 | 0.21 | 0.018 |
| 差值 | 约 1.92 秒 |
| 2026 年 8 月 | 发布补丁 — PaperCut NG 26.0.3 |
| 2026 年 8 月 | 与厂商协调进行公开披露 |