OpenProject 13.0.6 安全修复详解:Project Storage 成员页面的会话校验问题

OpenProject 13.0.6 安全修复详解:Project Storage 成员页面的会话校验问题 OpenProject 13.0.6 安全修复详解Project Storage 成员页面的会话校验问题【免费下载链接】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/openprojectOpenProject 13.0.6 是发布于 2023-10-13 的一个维护版本核心内容是对「Project storage members」项目文件存储成员连接状态页面可被未登录会话直接访问的问题进行修复。本文将围绕该修复展开结合 storages 模块的控制器、路由与回归测试源码说明该页面的功能定位、漏洞成因、修复后的访问控制链路以及如何通过测试验证修复效果帮助运维与开发人员理解本次补丁的实际意义。版本概览与升级建议项目内容版本号13.0.6发布日期2023-10-13发布类型Bug fix 维护版本修复内容Project storage members 页面无需会话即可访问官方发布说明明确建议该版本包含若干缺陷修复bug fixes推荐升级到最新版本。对于已经启用文件存储File storages模块、尤其是使用 Nextcloud / SharePoint / OneDrive 等自动托管文件夹automatically managed project folders功能的部署本次修复直接关系到成员连接状态页面的访问安全应优先安排升级。背景什么是 Project storage members 页面在 OpenProject 的 storages 模块中当管理员在项目设置里为项目关联文件存储并开启「自动托管项目文件夹」后系统需要为项目成员提供对远端存储如 Nextcloud的访问能力。为此项目设置下提供了一组成员管理页面其中Project storage members项目存储成员连接状态页面用于展示项目中每个用户类型成员与当前存储的 OAuth 连接状态各成员是否已授权、未授权或角色缺少存储权限等具体状态未连接成员应通过哪条链接登录存储完成授权。从路由定义可以看到该页面的挂载位置# modules/storages/config/routes.rb resources :project_storages, controller: /storages/admin/project_storages, except: %i[index show] do resources :members, controller: /storages/project_settings/project_storage_members, only: %i[index] end也就是说该页面是嵌套在单个 project_storage 资源下的members子资源仅开放index一个动作实际请求路径形如projects/:project_id/project_storages/:project_storage_id/members本次修复的漏洞点未登录即可访问13.0.6 修复的问题是Project storage members 页面在没有会话session的情况下可以被直接访问。该页面会列出项目成员与存储的连接状态属于敏感信息未登录访问意味着匿名用户可能获取到项目成员与外部存储的连接情况因此在修复中补上了强制登录与授权检查。修复后的访问控制链路源码级解析从当前仓库源码看该页面最终由Storages::ProjectSettings::ProjectStorageMembersController处理其继承关系与回调决定了访问控制如何生效# modules/storages/app/controllers/storages/project_settings/project_storage_members_controller.rb class Storages::ProjectSettings::ProjectStorageMembersController Projects::SettingsController menu_item :settings_project_storages before_action :find_project_by_project_id before_action :find_project_storage, only: %i[index] def index project_users Member .visible .of_project(project) .joins(:principal) .preload(roles: :role_permissions, principal: :remote_identities) .where(principal: { type: User }) .paginate(page: page_param, per_page: per_page_param) render /storages/project_settings/project_storage_members/index end ... end关键点在于其父类Projects::SettingsController的两个前置回调# app/controllers/projects/settings_controller.rb class Projects::SettingsController ApplicationController before_action :find_project_by_project_id before_action :authorize def show; end end其中authorize是 OpenProject 的权限校验入口它在用户未登录时最终会走到ApplicationController#deny_access# app/controllers/application_controller.rb def deny_access(not_found: false) if User.current.logged? not_found ? render_404 : render_403 else require_login end end由此构成完整的防护链路请求进入ProjectStorageMembersController#index前先执行find_project_by_project_id定位项目随后执行继承自Projects::SettingsController的authorize对当前用户进行登录态与项目权限校验若用户未登录authorize内部触发deny_access进而调用require_login跳转到登录页而不是渲染成员列表只有已登录且对项目设置具备相应权限的用户才能进入index动作并加载成员数据。此外index动作在数据查询层面也做了约束仅查询Member.visible且principal.type User的记录并预加载角色权限与remote_identities远端身份用于后续在视图中展示每个用户的连接状态。回归测试修复行为如何被固化该修复对应的回归测试位于modules/storages/spec/features/view_project_storage_members_spec.rb其中第一个用例直接验证了「未登录不可访问」的预期行为it cannot be accessed without being logged in do visit project_settings_project_storage_members_path(project, project_storage_id: project_storage.id) expect(page).to have_title(Sign in | OpenProject) expect(page).to have_no_text(Members connection status) end该用例断言未登录访问成员页面时会被重定向到 OpenProject 的登录页页面标题为 Sign in | OpenProject且页面上不会出现 Members connection status 字样从而确保敏感信息不会被未认证用户看到。同一测试文件中还覆盖了相关的授权语义无查看成员权限的登录用户可以进入页面但看不到任何成员显示 No members to display.有view_members权限的用户可以逐项看到成员的连接状态文案包括 Connected、Not connected. The user should login to the storage via the following link.、User role has no storages permissions 等SSO 场景当存储通过 OIDC SSO 认证时未走 SSO 登录的用户显示 Not connectable...已走 SSO 但尚未连接的用户显示 Not yet connected, SSO should automatically connect them, once looking at files.占位用户placeholder与用户组不展示成员列表只针对用户类型placeholder_user与group不在列表中项目无成员时显示空结果提示。从这些用例可以推断该页面的访问控制遵循「未登录一律拒绝、已登录再按view_members等权限细分」的策略13.0.6 的修复正是把「未登录直接放行」这一缺口补齐。修复的工程意义与运维建议从工程角度看本次修复虽小但具有典型的代表性意义敏感页面必须走统一认证链路OpenProject 通过Projects::SettingsController的authorize前置回调统一管控项目设置类页面的访问任何新加入该继承体系的控制器都会自动获得登录与权限校验避免开发者遗漏回归测试先行以view_project_storage_members_spec.rb为代表的 feature spec 把「未登录不可访问」固化为可执行断言防止后续重构中再次回退信息暴露风险成员连接状态页面会暴露「哪些成员接入了哪些外部存储」的信息属于需要保护的内部细节未认证访问修复属于低风险但必要的安全加固。对于运维人员建议将 13.0.6 及以上版本纳入升级计划尤其是启用了 storages 模块Nextcloud / SharePoint / OneDrive 集成的生产环境升级后可通过匿名或未登录浏览器访问projects/:project_id/project_storages/:project_storage_id/members进行抽检确认会跳转登录页而非直接渲染成员列表如需在本地验证该行为可运行对应回归测试bundle exec rspec modules/storages/spec/features/view_project_storage_members_spec.rb若使用旧版本且暂无法升级可考虑通过反向代理或 Web 应用防火墙限制该路径的匿名访问作为临时缓解。小结OpenProject 13.0.6 以一次精准的访问控制修复堵住了 Project storage members 页面的未认证访问缺口。本文从 13.0.6 发布说明出发梳理了该页面的功能定位控制器源码、修复后由authorize到require_login的完整防护链路父类控制器、ApplicationController以及固化该行为的回归测试。对于正在使用或计划引入 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),仅供参考