CVE-2026-31939 Overview
CVE-2026-31939 is a path traversal vulnerability affecting Chamilo LMS, an open-source learning management system. The vulnerability exists in the main/exercise/savescores.php file, where user input from $_REQUEST['test'] is concatenated directly into a filesystem path without proper canonicalization or traversal checks. This flaw allows authenticated attackers to delete arbitrary files on the server by manipulating the test parameter with directory traversal sequences.
Critical Impact
Authenticated attackers can exploit this path traversal vulnerability to delete arbitrary files on the server, potentially causing data loss, service disruption, or enabling further attacks by removing security controls or configuration files.
Affected Products
- Chamilo LMS versions prior to 1.11.38
- HotPotatoes exercise module in affected Chamilo LMS versions
- Installations using the savescores.php and exercise.php endpoints
Discovery Timeline
- 2026-04-10 - CVE CVE-2026-31939 published to NVD
- 2026-04-13 - Last updated in NVD database
Technical Details for CVE-2026-31939
Vulnerability Analysis
This vulnerability is classified as CWE-22 (Improper Limitation of a Pathname to a Restricted Directory), commonly known as Path Traversal or Directory Traversal. The flaw occurs in the HotPotatoes exercise scoring functionality within Chamilo LMS, specifically in the main/exercise/savescores.php file.
The vulnerable code directly concatenates user-supplied input from the $_REQUEST['test'] parameter into a filesystem path that is subsequently passed to a file deletion function (my_delete()). Without proper validation or path canonicalization, an attacker can inject directory traversal sequences (such as ../) to escape the intended document directory and target arbitrary files on the server.
The impact includes potential deletion of critical system files, configuration files, user data, or security controls. An attacker could leverage this to cause denial of service, remove audit logs, or set up conditions for further exploitation.
Root Cause
The root cause is the direct concatenation of untrusted user input ($_REQUEST['test']) into a filesystem path without implementing path canonicalization, allowlist validation, or traversal sequence filtering. The application constructs a file path by combining the document path with user input and a user ID suffix, then passes this to the my_delete() function without verifying that the resulting path remains within the intended directory boundaries.
Attack Vector
The attack is network-based and requires low-privilege authentication to the Chamilo LMS platform. An authenticated user can craft a malicious request to the savescores.php endpoint with a specially crafted test parameter containing path traversal sequences. For example, by submitting test=/../../../etc/target (adjusted for the specific server configuration), the attacker can manipulate the file deletion path to target files outside the intended document directory.
The following code shows the security patch applied by the Chamilo development team:
$this_section = SECTION_COURSES;
$documentPath = api_get_path(SYS_COURSE_PATH).$courseInfo['path']."/document";
-$test = $_REQUEST['test'];
+$test = $_REQUEST['test'] ?? '';
$full_file_path = $documentPath.$test;
+$fileToDelete = $full_file_path.$_user['user_id'].".t.html";
-my_delete($full_file_path.$_user['user_id'].".t.html");
+if (!Security::check_abs_path($fileToDelete, $documentPath.'/')) {
+ api_not_allowed(true);
+}
+
+my_delete($fileToDelete);
$TABLETRACK_HOTPOTATOES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES);
$TABLE_LP_ITEM_VIEW = Database::get_course_table(TABLE_LP_ITEM_VIEW);
-$score = $_REQUEST['score'];
+$score = isset($_REQUEST['score']) ? Security::remove_XSS($_REQUEST['score']) : '';
$origin = api_get_origin();
$learnpath_item_id = intval($_REQUEST['learnpath_item_id']);
$lpViewId = isset($_REQUEST['lp_view_id']) ? intval($_REQUEST['lp_view_id']) : null;
Source: GitHub Commit Update
A similar fix was applied in main/exercise/exercise.php:
// Teacher change exercise
break;
}
+
+ // Security: reject path traversal attempts (CWE-22)
+ if (!Security::check_abs_path($documentPath.$file, $documentPath.'/')) {
+ api_not_allowed(true);
+ }
+
// deletes an exercise
$imgparams = [];
$imgcount = 0;
Source: GitHub Commit Update
Detection Methods for CVE-2026-31939
Indicators of Compromise
- HTTP requests to /main/exercise/savescores.php containing path traversal sequences such as ../, ..%2f, or URL-encoded variants in the test parameter
- Unexpected file deletions in system directories or outside the Chamilo document paths
- Web server access logs showing suspicious requests with traversal patterns targeting exercise endpoints
- Audit log entries indicating file operations on paths outside expected course document directories
Detection Strategies
- Implement web application firewall (WAF) rules to detect and block requests containing path traversal sequences in query parameters
- Monitor HTTP request logs for patterns containing .., %2e%2e, or other encoded traversal attempts targeting Chamilo exercise endpoints
- Deploy file integrity monitoring (FIM) on critical system and application files to detect unauthorized deletions
- Configure intrusion detection systems to alert on anomalous file deletion events outside normal application behavior
Monitoring Recommendations
- Enable detailed logging for the Chamilo LMS application, particularly for file operations and the exercise module
- Set up real-time alerting for any file deletion operations that occur outside the expected document path hierarchy
- Monitor for repeated failed access attempts or unusual patterns of requests to savescores.php and exercise.php endpoints
- Implement centralized log aggregation to correlate potential exploitation attempts across multiple server instances
How to Mitigate CVE-2026-31939
Immediate Actions Required
- Upgrade Chamilo LMS to version 1.11.38 or later immediately to patch this vulnerability
- Review web server access logs for any historical exploitation attempts targeting the affected endpoints
- Conduct a file system integrity check to identify any unauthorized file deletions that may have occurred
- Restrict network access to Chamilo administrative and exercise endpoints where possible until patching is complete
Patch Information
The vulnerability has been fixed in Chamilo LMS version 1.11.38. The patch implements proper path validation using the Security::check_abs_path() function, which verifies that the constructed file path remains within the authorized document directory before any file operations are performed. Additionally, the fix adds XSS protection for the score parameter and improves null handling for user input.
For detailed patch information, refer to:
Workarounds
- Deploy a web application firewall (WAF) rule to block requests containing path traversal sequences (e.g., ../, ..%2f) in the test parameter
- Temporarily disable access to the /main/exercise/savescores.php and /main/exercise/exercise.php endpoints if HotPotatoes functionality is not required
- Implement server-level access controls to restrict the Chamilo web user's file deletion permissions to only the document directory
- Apply network-level restrictions to limit access to the Chamilo LMS instance to trusted IP ranges until patching can be completed
# Example: Apache mod_rewrite rule to block path traversal attempts
RewriteEngine On
RewriteCond %{QUERY_STRING} (\.\./) [NC,OR]
RewriteCond %{QUERY_STRING} (\.\.%2f) [NC,OR]
RewriteCond %{QUERY_STRING} (%2e%2e/) [NC]
RewriteRule ^main/exercise/savescores\.php - [F,L]
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


