OpenProject 12.5.4 安全补丁深度解析:2FA 会话失效与密码重置令牌吊销机制

发布时间:2026/9/16 13:29:13
OpenProject 12.5.4 安全补丁深度解析:2FA 会话失效与密码重置令牌吊销机制 OpenProject 12.5.4 安全补丁深度解析2FA 会话失效与密码重置令牌吊销机制【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject导读OpenProject 12.5.4发布于 2023-05-02是一次面向安全加固的补丁版本重点修复了两个被负责任披露的安全问题一是启用/注册首个双因素认证2FA设备后既有登录会话未被终止CVE-2023-31140二是用户成功修改密码后先前发出的密码重置链接仍然有效#48036。本文以该版本发布说明为骨架结合仓库内modules/two_factor_authentication、app/services/sessions、app/services/users等模块的源码实现逐层还原这两个漏洞的成因、修复方案、底层调用链与配置关联同时梳理同版本修复的其余 bug帮助运维与安全人员理解升级的必要性及背后的防御设计。版本概览一次建议立即升级的安全维护版12.5.4 与常规功能版本不同其核心定位是安全修复发布说明明确表示The release contains two security related bug fixes and we recommend updating to the newest version包含两个安全相关 bug 修复建议升级到最新版本。两个安全问题均由安全研究员 Vaishnavi Pardeshi 负责任披露且都涉及认证会话与令牌的生命周期管理这一共性主题问题编号类型修复思路2FA 激活后既有会话仍有效CVE-2023-31140 / #48035会话失效缺失首次 2FA 设备注册确认后主动终止该账号的其它登录会话密码重置链接在改密后仍可用#48036令牌吊销缺失成功改密后主动吊销该账号所有有效的密码重置令牌两处修复共享同一个底层设计哲学在账号安全状态发生跃迁安全等级提升或凭据变更的瞬间同步回收旧的信任凭证会话、令牌。下文将分别深入这两条修复链路。修复一CVE-2023-31140 —— 2FA 激活后终止既有会话漏洞成因OpenProject 的多因素认证由modules/two_factor_authentication模块实现支持 TOTP、短信 SMS、WebAuthn 等设备类型。在 12.5.4 之前存在两个会话残留场景用户自助注册用户在账号上注册并确认第一个 2FA 设备后该账号此前已登录的会话没有被终止管理员代管管理员代替用户创建手机 2FA 设备后该用户已存在的会话同样没有被终止。这意味着攻击者若在此之前已获得用户的有效会话例如通过会话窃取即使 2FA 已启用旧会话依旧可以绕过 2FA 保护继续使用削弱了 2FA 本身的安全价值。修复实现按是否为本人操作分流处理修复逻辑位于 2FA 设备确认完成的回调中。在 modules/two_factor_authentication/app/controllers/two_factor_authentication/base_controller.rb当设备确认保存成功后执行logout_other_sessions unless has_default仅当这是用户的第一个设备、尚无默认设备时触发if confirm_and_save(result) logout_other_sessions unless has_default end随后的核心方法同文件 第 201-209 行根据操作者是否为账号本人选择不同的会话清理策略def logout_other_sessions if current_user target_user Rails.logger.info { First 2FA device registered for #{target_user}, terminating other logged in sessions. } ::Sessions::DropOtherSessionsService.call!(target_user, session) else Rails.logger.info { First 2FA device registered for #{target_user}, terminating logged in sessions. } ::Sessions::DropAllSessionsService.call!(target_user) end end两种分支分别对应两种真实场景本人注册设备调用 app/services/sessions/drop_other_sessions_service.rb 中的DropOtherSessionsService.call!按当前会话 ID 排除自身后删除该用户其余全部会话从而保留用户当前正在执行 2FA 配置的会话、终止其它历史会话::Sessions::UserSession .for_user(user) .where.not(session_id: session.id.private_id) .delete_all管理员代用户注册设备当前操作者不是目标用户无法保留当前会话因此调用 app/services/sessions/drop_all_sessions_service.rb 中的DropAllSessionsService.call!将该账号的全部会话一次性删除包括目标用户所有正在活跃的会话迫使其下次登录必须通过 2FA 验证::Sessions::UserSession .for_user(user) .delete_all从源码结构看会话清理基于 ActiveRecord 会话存储Sessions::UserSession因此该修复依赖于数据库会话session_store采用数据库/ActiveRecord 后端才能按用户批量删除若部署使用纯 Cookie 会话存储则无法精确按用户定位会话。这是使用该功能时需要注意的部署前提。修复二#48036 —— 改密后吊销密码重置令牌漏洞成因OpenProject 的密码找回流程是典型的邮箱链接 一次性令牌模型用户请求重置密码系统生成恢复令牌并通过邮件发送含链接的重置确认信用户在邮件到达前的某个时间点通过正常渠道如已登录会话成功修改了密码但此前发出的重置链接并未随之失效在令牌有效期内依旧可被用于再次设置新密码。该漏洞的风险在于若攻击者截获了重置邮件或邮箱被入侵即使账号持有人已主动修改密码攻击者仍可在令牌有效期内利用该链接劫持账号。修复实现改密成功后统一吊销恢复令牌修复落点在 app/services/users/change_password_service.rb。密码修改成功current_user.save通过后服务依次执行if current_user.save invalidate_tokens invalidate_other_sessions log_success # ... end其中invalidate_tokens委托给 app/services/users/drop_tokens_service.rbdef call!(clear_invitation_tokens: true) invalidate_recovery_tokens invalidate_invitation_tokens if clear_invitation_tokens end def invalidate_recovery_tokens Token::Recovery.where(user:).delete_all end也就是说用户成功修改密码的那一刻其名下所有Token::Recovery密码恢复令牌被一次性全部删除任何尚未使用的重置链接随即失效——这正是发布说明中所描述的actively revoking any active password reset tokens for user accounts having changed their passwords successfully within the application在应用内成功改密后主动吊销所有有效的密码重置令牌。令牌模型细节有效期与唯一性为了理解在令牌有效期内仍可用的表述需要结合令牌模型实现app/models/token/recovery.rb 定义了Token::Recovery的有效期为1.day一天并通过ExpirableTokenmixin 实现过期判定与过期清理见 app/models/token/expirable_token.rbexpired?判断expires_on是否已过。app/models/token/base.rb 中before_save :delete_previous_token保证每个用户每种令牌类型只有一条有效记录generate_token_value使用SecureRandom.hex(32)生成不可预测的令牌值。这也解释了修复前的场景令牌的唯一性约束只发生在生成新令牌时删除旧令牌而改密这条路径此前并不触发令牌清理因此已发出的重置链接会一直存活到 1 天有效期结束。12.5.4 通过把令牌吊销挂接到改密服务补上了这个生命周期缺口。请求端的双重校验在控制器层app/controllers/account_controller.rb 的set_recovered_password在重置密码成功后还会执行token.destroy!销毁当前使用的令牌结合find_valid_recovery_token对令牌有效性的校验形成了服务端主动吊销 请求端用完即焚的双保险。关联配置会话清理选项与临时规避方案发布说明为 CVE-2023-31140 提供了一个临时规避方案workaround用户在注册首个 2FA 设备后手动退出登录以终止其它活跃会话。但说明同时提醒这一行为依赖于 OpenProject 的会话清理配置需要确认相关配置未被覆盖。相关配置项见 docs/installation-and-operations/configuration/README.md 的 Setting session options 一节drop_old_sessions_on_logout默认true用户登出时销毁该用户的所有旧会话。通过环境变量OPENPROJECT_DROP__OLD__SESSIONS__ON__LOGOUTfalse可以关闭——如果被关闭则手动登出终止其它会话这一规避手段将不再生效。drop_old_sessions_on_login默认false登录时销毁该用户的旧会话。开启方式为OPENPROJECT_DROP__OLD__SESSIONS__ON__LOGINtrue这也可以作为一种额外的会话收紧策略。因此若运维人员在生产环境调整过上述变量应确认其取值否则临时规避方案可能无效最稳妥的做法仍是升级到 12.5.4 及以上版本。同版本其它修复与变更除两个安全修复外12.5.4 还包含若干常规 bug 修复发布说明原文Google reCAPTCHA v2 / v3 实现变更#44115其中会记录::Recaptcha::Entry及所用版本recaptcha_version并根据版本选择不同的验证参数同时支持 hCaptcha、Cloudflare Turnstile 等验证后端的配置切换。用户动态上一页链接丢失用户参数#47855分页/导航链接在跳转上一页时未保留用户过滤参数。工作包 HTML 标题被无谓截断#47876页面title生成逻辑对工作包标题做了不必要的截断。Firefox 下用户内容表格换行间距异常#48027用户富文本内容中的表格在 Firefox 渲染时出现错误间距。发布说明特别感谢了社区成员对 bug 的反馈与修复协助其中点名感谢了报告并定位问题的 Björn Schümann。安全披露流程与后续建议两个漏洞均由安全研究员通过负责任披露responsible disclosure渠道上报。OpenProject 的安全策略文档 docs/security-and-privacy/statement-on-security/README.md 明确了完整的披露流程安全问题应通过邮件securityopenproject.com支持 PGP 加密密钥指纹BDCF E01E DE84 EA19 9AE1 72CE 7D66 9C6D 4753 3958公钥文件见 security-at-openproject.com.asc或 GitHub Security Advisory 渠道私下提交报告中应包含漏洞描述、受影响函数与版本、可复现步骤、利用证据及安全影响评估在得到同意前不得公开披露且只允许针对自己的实例进行测试所有中危medium CVSS及以上的已知问题都会以 CVE 形式发布安全公告同时同步到发布说明。对运维与安全团队的实际建议优先升级12.5.4 为安全维护版建议尽快升级到该版本或更高版本核对会话配置检查OPENPROJECT_DROP__OLD__SESSIONS__ON__LOGOUT与OPENPROJECT_DROP__OLD__SESSIONS__ON__LOGIN的取值确保会话清理策略符合安全基线确认会话存储后端2FA 会话失效依赖 ActiveRecord 会话存储自定义会话存储方案需评估兼容性关注后续公告安全修复会同步出现在发布说明与安全公告中可订阅安全邮件列表及时获取通知。小结OpenProject 12.5.4 用两个看似独立的修复展示了账号安全生命周期管理的两条重要实践启用更强的认证手段2FA后必须回收旧的会话凭证以及凭据变更改密后必须吊销所有旧的恢复令牌。两者在仓库中分别由Sessions::DropOtherSessionsService/Sessions::DropAllSessionsService与Users::DropTokensService承担并统一挂接在 2FA 设备确认与密码修改这两个安全状态跃迁点之上。理解这套安全跃迁即回收旧凭证的机制比单纯升级版本更有助于构建和维护安全的 OpenProject 部署。【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考