OpenProject 17.1.1 发布解析:9 项安全漏洞修复、越权与路径穿越原理及升级建议
2026/9/16 15:13:44 网站建设 项目流程

OpenProject 17.1.1 发布解析:9 项安全漏洞修复、越权与路径穿越原理及升级建议

【免费下载链接】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 17.1.1 发布说明 撰写,结合仓库源码(API v3 端点、Costs 模块控制器、BIM/BCF 模块等)深度解析本次补丁修复的安全漏洞成因、受影响端点与修复思路,并给出升级建议。阅读本文后,你将掌握 17.1.1 的完整变更清单、每个 CVE 的攻击路径与修复要点,并能据此评估自身实例的暴露面与升级优先级。

OpenProject 于 2026-02-18 发布了 17.1.1 版本。这是一个以安全修复为主的补丁版本:共修复 9 个 CVE 安全漏洞(含 2 个可导致远程代码执行 RCE 的路径穿越漏洞),以及 7 个功能 Bug。官方在发布说明中明确建议所有用户升级到最新版本。本文以该发布说明为主体,逐项拆解每个漏洞的技术细节,并深入对应源码位置,帮助运维人员与开发者理解问题本质、做好升级与自查。

版本概览

项目内容
版本号17.1.1
发布日期2026-02-18
发布类型安全补丁(Bugfix + Security)
安全漏洞9 个 CVE(含 2 个可致 RCE 的路径穿越)
功能 Bug 修复7 个
官方建议强烈建议升级到最新版本

官方版本跟踪链接:OpenProject 17.1.1 版本页。以下漏洞大多由社区安全研究员通过 YesWeHack.com OpenProject Bug Bounty 赏金计划 报告,该计划由欧盟委员会(European Commission)赞助。

一、Security fixes:9 个 CVE 深度解析

1. CVE-2026-26966:/api/v3/queriesPOST 越权创建项目查询(Improper Access Control)

漏洞描述/api/v3/queries端点存在失效的访问控制,允许普通已认证用户在没有足够权限的情况下创建私有项目查询(private project queries)

攻击方式:攻击者复用管理员生成的有效请求,将请求中的 session cookie 与 CSRF token 替换为低权限用户的对应凭据后重放,后端仍会接受该请求并成功创建查询。该操作本应仅限具备相应角色的授权用户执行,暴露了查询创建流程中缺失或不充分的授权检查。

源码印证:查询 API 定义于 queries_api.rb。可以看到:

  • post &::API::V3::Utilities::Endpoints::Create.new(model: Query).mount(L100-L102)直接挂载了通用的 Create 端点;
  • route_param :id下的getpatchdelete等操作均通过authorize_by_policy(:show)authorize_by_policy(:update)authorize_by_policy(:destroy)做了基于QueryPolicy的授权(L104-L146);
  • 对比可见,POST 创建路径缺少与之对等的策略级授权校验,这正是越权创建查询的根源。17.1.1 的修复方向即在创建端点补充权限检查。

自查与加固:升级后可用低权限账号向/api/v3/queries发起 POST 尝试创建私有查询,验证是否被拒绝;同时建议审计是否存在管理员与低权限用户共享会话环境的代理/网关配置。

2. CVE-2026-26968:/api/v3/capabilities未授权枚举私有项目信息

漏洞描述/api/v3/capabilities端点允许通过将 principal 指定为内置管理员用户 ID,未授权枚举私有项目名称与详细权限信息。虽然 API 正确阻止了查询其他用户的 capabilities,但内置 Admin 账号仍可被解析(resolvable)。

危害放大:由于项目使用递增的整型 ID,且内置管理员对所有项目可见,攻击者可借此测绘(mapping)整个 OpenProject 实例:遍历 ID 即可获得全部(含私有)项目清单及其权限结构,为后续针对性攻击提供情报。

源码印证:Capabilities API 定义于 capabilities_api.rb,其列表与详情分别挂载SqlIndexSqlShow端点(L33-L49)。问题在于 principal 解析逻辑对内置管理员未做与普通用户同等的隔离,导致权限校验被绕过。

自查与加固:升级后以低权限用户请求/api/v3/capabilities?filters=[{"principal":{"operator":"=","values":["1"]}}](1 为内置 admin 常见 ID),确认返回 403/空结果而非项目数据。此外可结合部署层限制 API 的匿名/低权限访问。

3. CVE-2026-26969:项目名称 HTML 注入

漏洞描述:应用对项目名称这一用户输入未做充分清洗(improper sanitization),攻击者可在项目名中注入任意 HTML 标签,改变页面结构;后续创建工作包(work package)时 payload 被执行

影响:属于存储型 HTML 注入,可造成页面篡改、内容伪造;若结合浏览器特性或与其他漏洞组合,可能进一步升级为 XSS 类攻击。

修复要点:在项目名称写入与渲染链路中补充输出编码/白名单清洗。升级后建议创建含<script><img onerror=...>等项目名进行回归验证,确认前端与 API 返回均为转义文本。

4. CVE-2026-26970:Wiki 更新邮件中的 HTML 注入(wiki updated mailer)

漏洞描述:wiki 更新邮件发送功能未正确转义 HTML 标签。攻击路径为:

  1. 攻击者(或注册开放时任何用户)在用户名中携带 HTML 标签;
  2. 获得 wiki 页面新增/编辑权限后,其作者标签(author tag)在邮件中未转义,注入 HTML。

影响:邮件客户端中可呈现恶意 HTML,造成钓鱼、内容伪造或(在宽松邮件客户端下)类 XSS 行为。

修复要点:在邮件模板渲染用户名/作者信息处强制 HTML 转义。升级后可通过构造特殊用户名并触发 wiki 更新邮件来验证。

5. CVE-2026-26971:Hourly Rates 控制器 IDOR —— 跨项目删除小时费率

漏洞描述:Costs 模块中,一个按项目限定(project-scoped)的小时费率更新端点,通过发送省略 user 参数的构造请求,即可删除目标用户在所有项目中的小时费率

根因:请求仅针对 URL 中的项目(:project_id)做授权,但删除查询并未按该项目作用域限定,造成跨项目失效的访问控制(水平越权,horizontal privilege escalation)。

源码印证:控制器位于 hourly_rates_controller.rb。关键在update动作:当params中不含"user"时走delete_rates分支(L96-L103),而delete_rates的实现为:

def delete_rates(user, project) if project.present? user.rates.where(project:).delete_all else user.default_rates.delete_all end end

从源码结构看,该方法接受的是控制器内部解析出的@project@user,而find_userparams[:id].blank?时回退为User.current(L146-L153)。若请求省略 user 参数,删除目标即从当前用户演变为可通过@project解析的其他用户,且删除范围若未严格限定于当前项目,便会波及该用户在所有项目下的费率。这正是 17.1.1 修复的作用域校验点。

自查与加固:升级后,使用具有某项目edit_hourly_rates权限的低权限账号,构造省略user参数的 update 请求,确认删除操作被拒绝或严格限制在本项目内。

6. CVE-2026-26976:注册邮箱字段 HTML 注入,向实例所有者发送恶意通知邮件

漏洞描述:当启用匿名注册时,未认证攻击者可在注册流程(/account/register)的邮箱字段提交恶意 payload。即使注册因免费版 10 活跃用户上限失败,系统仍会向实例所有者/管理员发送"用户数已达上限"的通知邮件,且该邮件未转义地回显了恶意邮箱 payload(body/subject/content 均可注入 HTML)。

影响:钓鱼、内容伪造,在宽松邮件客户端下可能产生管理员收件箱中的类 XSS 行为。

源码印证:用户上限逻辑位于 enterprise_token.rb(活跃用户数限制相关校验)。问题本质是通知邮件的渲染链路缺少对用户可控字段的输出编码

自查与加固:升级后以攻击性邮箱字符串(如a"<img src=x onerror=...>"@example.com)触发一次注册尝试,检查管理员收到的限额通知邮件是否原样输出未转义内容。

7. CVE-2026-27006:BIM 版 BCF 模块路径穿越 —— 任意文件上传,可致 RCE

漏洞描述BIM 版本中,具备 BCF 模块访问权限的已认证攻击者,可利用 BCF 导入功能的路径穿越漏洞,向服务器上任意可写目录写入任意文件。对基于 docker-compose 的部署,可进一步利用缓存反序列化(cache deserialization)扩展为远程代码执行(RCE)

技术背景:BCF(BIM Collaboration Format)是 BIM 领域的协作格式,OpenProject BIM 版通过 BCF 导入功能解析外部 BCF 文件包(zip 结构)。问题在于解包/落盘时未对条目路径做规范化校验,允许../等穿越序列逃逸目标目录。相关代码分布于 modules/bim/app/controllers/bim/bcf/issues_controller.rb、modules/bim/app/models/bim/bcf/issue.rb 以及 bcf_xml_seeder.rb 等导入链路。

修复要点:对 BCF 压缩包内每个条目执行路径规范化(resolve + 前缀校验),拒绝含穿越序列的条目;同时对文件落盘目录与缓存目录实施最小权限。BIM/BCF 用户应优先升级

8. CVE-2026-27019:入站邮件附件路径穿越 —— 任意文件写入与 RCE

漏洞描述:当 OpenProject 配置为接收并处理入站邮件时,攻击者可发送携带特制附件的邮件,附件被写入文件系统预定义位置之外的任意路径。凡是openproject系统用户可写的位置均受影响,并可升级为远程代码执行

影响面:启用邮件接收(mail-in / incoming email handler)的实例直接暴露。该功能常见于"邮件创建/回复工作包"场景。

修复要点:对入站邮件附件的存储路径做严格规范化与白名单约束,确保文件名/路径不可穿越附件存储根目录;同时建议以最小权限运行openproject系统用户、对附件目录启用强制访问控制。

9. 安全修复小结表

CVE类型受影响模块/端点攻击者前提最坏影响
CVE-2026-26966越权访问控制/api/v3/queriesPOST低权限已认证用户未授权创建私有项目查询
CVE-2026-26968越权访问控制/api/v3/capabilities低权限已认证用户枚举私有项目/实例测绘
CVE-2026-26969HTML 注入项目名称可创建/编辑项目的用户存储型页面篡改,工作包创建时执行
CVE-2026-26970HTML 注入Wiki 更新邮件可编辑 wiki 的用户邮件内容伪造/钓鱼
CVE-2026-26971IDOR 水平越权Costs 小时费率控制器具项目费率编辑权限的用户跨项目删除他人小时费率
CVE-2026-26976HTML 注入/account/register通知邮件未认证(注册开放时)向管理员投递恶意邮件
CVE-2026-27006路径穿越 → 任意文件写 → RCEBIM/BCF 导入BCF 模块已认证用户任意文件写入,docker-compose 下 RCE
CVE-2026-27019路径穿越 → 任意文件写 → RCE入站邮件附件可向实例发送邮件的攻击者任意文件写入,可升级 RCE

(注:上述 9 个 CVE 中的第 9 项信息请以官方 GitHub Advisory 为准,完整公告见发布说明中对应链接。)

二、Bug fixes:7 个功能修复清单

17.1.1 同时修复了 7 个功能 Bug,覆盖前端、国际化、文档模块、邮件链接、导出与管理员安全边界:

问题类型描述
BugfixDocuments 模块:iOS 上缩放问题(#71023)
Bugfix简体中文(zh-TW)环境的 Seeding 失败(#71869)
Bugfix每次 OpenProject 更新后,默认文档类型被重复创建(#71877)
Bugfix通知邮件中的外部链接未被捕获(#71907)
Bugfix路径中含编码空格的外部链接跳转到 OpenProject 首页(#71931)
Bugfix封面图片文件存储损坏时,会议 PDF 导出报错(#71945)
Bugfix最后一个管理员可以删除自己(#71980)

其中值得关注的两项:

  • 最后一个管理员自删(#71980):这是典型的管理员锁死问题——若实例仅剩一个管理员账号且可被删除,将导致实例失去管理入口。该修复通常会在删除操作前校验管理员数量下限;
  • zh-TW seeding 失败(#71869):影响db:seed及安装向导在新语言环境下的初始化流程,关系到 db/seeds.rb 与各语言 locale 文件的完整性。

三、升级建议与自查清单

升级优先级评估

结合漏洞危害与利用前提,建议按以下优先级安排升级:

  1. 立即升级:启用入站邮件处理(CVE-2026-27019)、使用 BIM 版并开放 BCF(CVE-2026-27006)的实例,两者均可能导向 RCE;
  2. 尽快升级:开放匿名注册的实例(CVE-2026-26976)、多租户/多项目共用实例(CVE-2026-26966、CVE-2026-26968、CVE-2026-26971);
  3. 随常规升级窗口处理:其余 HTML 注入类漏洞(CVE-2026-26969、CVE-2026-26970)。

升级后回归验证清单

  • 以低权限账号分别尝试 POST/api/v3/queries与查询/api/v3/capabilities,确认越权路径已封闭;
  • 创建含 HTML 标签的项目名与用户名,检查页面渲染与 Wiki/注册通知邮件均为转义输出;
  • 在 Costs 模块中构造省略user参数的费率更新请求,确认删除被限制于当前项目;
  • BIM 实例导入含../路径条目的 BCF 文件,确认被拒绝;
  • 入站邮件功能实例发送含特制文件名的附件,确认落盘路径被限制在附件根目录内。

四、致谢与参考

OpenProject 官方在发布说明中对社区成员 Andreas H. 及所有提交 Bug 报告的社区成员表达了感谢。本版本的安全漏洞主要由 YesWeHack.com 赏金计划研究员发现与报告,包括 slashx0x、syndrome_impostor、noidont、roro1702、yokokho、sam91281、pdowski、shafouzzz 等。

延伸阅读(仓库内)

  • 发布说明原文:docs/release-notes/17-1-1/README.md
  • 查询 API 实现:lib/api/v3/queries/queries_api.rb
  • Capabilities API 实现:lib/api/v3/capabilities/capabilities_api.rb
  • 小时费率控制器:modules/costs/app/controllers/hourly_rates_controller.rb
  • 用户上限校验:app/models/enterprise_token.rb
  • BIM/BCF 导入链路:modules/bim/app/controllers/bim/bcf/issues_controller.rb、modules/bim/app/models/bim/bcf/issue.rb

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询