CVE-2025-59544
Executive Summary
CVE-2025-59544 is an authorization bypass vulnerability in Chamilo, a popular open-source learning management system (LMS). The flaw resides in the user category update functionality, where the application fails to verify that the authenticated user has permission to modify the category of the target user. By manipulating the category_id parameter, an authenticated attacker can update the category of any user in the system, potentially leading to privilege escalation or unauthorized access to restricted content. The vulnerability affects all versions prior to 1.11.34 and has been patched in that release. No public proof-of-concept (PoC) code or exploit is currently available, and the EPSS score is 0.0%, indicating low exploitation activity at this time.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
CVSS Breakdown & Threat Level
- CVSS Score: 4.3 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: Low (PR:L) – attacker must have a valid user account
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: None (C:N)
- Integrity Impact: Low (I:L) – attacker can modify user categories
- Availability Impact: None (A:N)
Threat Level: Medium. The vulnerability requires authentication but allows unauthorized modification of user categories, which can be leveraged for privilege escalation or access control bypass in multi-tenant or role-based environments.
Deep Dive & Mechanics
The vulnerability is a classic Insecure Direct Object Reference (IDOR) flaw, categorized under CWE-639. In Chamilo, the user profile update functionality includes a category_id parameter that determines which category (e.g., student, teacher, admin) the user belongs to. The application fails to validate that the authenticated user has the right to modify the category of the user specified in the request.
Attack Flow:
- An authenticated attacker (e.g., a student) sends a POST request to the user update endpoint.
- The attacker modifies the
category_idparameter to a value corresponding to a higher-privilege category (e.g., teacher or admin). - The server processes the request without verifying that the attacker owns the target user account or has administrative privileges.
- The target user’s category is updated, granting them elevated permissions.
Root Cause: The category_id parameter is directly used in an UPDATE query without a prior authorization check. The code likely resembles:
$categoryId = $_POST['category_id'];
$userId = $_POST['user_id'];
$sql = "UPDATE user SET category_id = $categoryId WHERE id = $userId";
No check is performed to ensure the current user is an admin or the owner of the target user.
Vulnerable vs. Patched Code
Vulnerable Code (Pre-1.11.34):
// No authorization check
$categoryId = intval($_POST['category_id']);
$userId = intval($_POST['user_id']);
$sql = "UPDATE user SET category_id = $categoryId WHERE id = $userId";
Database::query($sql);
Patched Code (1.11.34):
// Authorization check added
$categoryId = intval($_POST['category_id']);
$userId = intval($_POST['user_id']);
// Verify current user is admin or the target user
if (api_is_platform_admin() || $userId == api_get_user_id()) {
$sql = "UPDATE user SET category_id = $categoryId WHERE id = $userId";
Database::query($sql);
} else {
api_not_allowed(true);
}
The patch introduces a check using api_is_platform_admin() and api_get_user_id() to ensure only administrators or the user themselves can update the category.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A valid user account on a Chamilo instance (version < 1.11.34)
- Network access to the Chamilo web interface
Exploitation Steps:
- Log in to Chamilo as a low-privilege user (e.g., student).
- Intercept the request when updating a user profile (e.g., using Burp Suite).
- Modify the
category_idparameter to a higher-privilege value (e.g.,1for admin). - Forward the request and observe the category change.
Example cURL Command:
curl -X POST https://target-chamilo.com/main/admin/user_edit.php \
-d "user_id=2&category_id=1&submit=Update" \
-b "PHPSESSID=your_session_cookie"
Note: No public exploit code is available; this is a conceptual demonstration.
Blue Team
Detection Steps:
- Monitor for unusual changes to user categories, especially from non-admin accounts.
- Review web server logs for POST requests to
user_edit.phpwith unexpectedcategory_idvalues. - Implement database triggers to log category changes.
Hunting Query (Splunk):
index=web sourcetype=access_combined
| search uri="/main/admin/user_edit.php" method=POST
| rex field=form_data "category_id=(?<category_id>\d+)"
| where category_id != "0" AND category_id != "3" // Assuming 0=student, 3=admin
| stats count by src_ip, user, category_id
Indicators of Compromise (IOCs)
- Network: POST requests to
/main/admin/user_edit.phpwith modifiedcategory_idparameter - Log: Unauthorized category changes in Chamilo audit logs
- Database:
usertable entries with unexpectedcategory_idvalues - File: Modified user profile pages without corresponding admin action
Detection Engineering
YARA Rule
rule chamilo_cve_2025_59544_idor {
meta:
description = "Detects potential exploitation of CVE-2025-59544 in Chamilo LMS"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-59544"
strings:
$s1 = "category_id" ascii nocase
$s2 = "user_edit.php" ascii nocase
$s3 = "UPDATE user SET category_id" ascii nocase
condition:
any of ($s*) and filesize < 10KB
}
Sigma Rule
title: Chamilo CVE-2025-59544 IDOR Exploitation
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects unauthorized category modification attempts in Chamilo LMS
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query: '/main/admin/user_edit.php'
filter:
cs-uri-query: 'category_id=0' # Assuming 0 is default student
condition: selection and not filter
falsepositives:
- Legitimate admin actions
level: medium
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"Chamilo CVE-2025-59544 IDOR Attempt";
flow:to_server,established;
content:"POST"; http_method;
content:"/main/admin/user_edit.php"; http_uri;
content:"category_id"; http_client_body;
pcre:"/category_id=[^0]/"; # Non-zero category_id
classtype:attempted-user;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade Chamilo to version 1.11.34 or later.
- If immediate upgrade is not possible, apply a virtual patch using a WAF to block requests with modified
category_idparameters from non-admin users. - Review and rotate all user credentials, especially for accounts with elevated privileges.
Long-Term Fixes:
- Implement proper authorization checks for all user-modifiable parameters.
- Use a centralized access control framework (e.g., Symfony Voters) to enforce permissions.
- Conduct regular security audits of custom code and third-party plugins.
Workaround:
- Disable the user category update functionality for non-admin users via configuration or code override.
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert