CVE-2026-32931 Overview
CVE-2026-32931 is an unrestricted file upload vulnerability (CWE-434) affecting Chamilo LMS, a popular open-source learning management system. The vulnerability exists in the exercise sound upload function, allowing an authenticated teacher to upload a PHP webshell by spoofing the Content-Type header to audio/mpeg. The uploaded file retains its original .php extension and is placed in a web-accessible directory, enabling Remote Code Execution (RCE) as the web server user (www-data).
Critical Impact
Authenticated attackers with teacher privileges can achieve full Remote Code Execution on vulnerable Chamilo LMS installations by uploading malicious PHP files through the exercise sound upload function.
Affected Products
- Chamilo LMS versions prior to 1.11.38
- Chamilo LMS versions prior to 2.0.0-RC.3
Discovery Timeline
- 2026-04-10 - CVE-2026-32931 published to NVD
- 2026-04-13 - Last updated in NVD database
Technical Details for CVE-2026-32931
Vulnerability Analysis
This vulnerability stems from insufficient file validation in the updateSound method within exercise.class.php. The vulnerable code relied solely on the Content-Type header provided by the client to validate uploaded files, checking only if the MIME type contained "audio" or "video" strings. This client-side validation is trivially bypassed by an attacker who can manipulate HTTP request headers.
When a file is uploaded through the exercise sound functionality, the application performs the following flawed validation:
if ($sound['size'] && (strstr($sound['type'], 'audio') || strstr($sound['type'], 'video')))
This check uses $sound['type'], which corresponds to the Content-Type header sent by the client—a value entirely under attacker control. By setting the Content-Type to audio/mpeg while uploading a file with a .php extension, the validation passes, and the malicious PHP file is moved to a web-accessible audio directory.
Root Cause
The root cause is improper input validation (CWE-434) in the file upload handling. The application trusts the client-supplied Content-Type header instead of performing server-side validation of the actual file content (magic bytes) or enforcing an allowlist of permitted file extensions. Additionally, the uploaded file retains its original filename and extension, allowing executable PHP files to be stored in web-accessible locations.
Attack Vector
The attack requires network access and low-privileged authentication (teacher role). An attacker can exploit this vulnerability through the following steps:
- Authenticate to Chamilo LMS with teacher credentials
- Navigate to the exercise sound upload functionality
- Craft a malicious HTTP request with a PHP webshell payload
- Spoof the Content-Type header to audio/mpeg
- Upload the file with a .php extension
- Access the uploaded webshell directly via the web-accessible audio directory
- Execute arbitrary commands as the www-data user
The security patch removed the vulnerable updateSound method entirely from exercise.class.php:
// Removed vulnerable method from exercise.class.php
// Source: https://github.com/chamilo/chamilo-lms/commit/8cbe660de267f2b6ed625433bdfcf38dee8752b4
- /**
- * changes the exercise sound file.
- *
- * @author Olivier Brouckaert
- *
- * @param string $sound - exercise sound file
- * @param string $delete - ask to delete the file
- */
- public function updateSound($sound, $delete)
- {
- global $audioPath, $documentPath;
- $TBL_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
-
- if ($sound['size'] && (strstr($sound['type'], 'audio') || strstr($sound['type'], 'video'))) {
- $this->sound = $sound['name'];
-
- if (@move_uploaded_file($sound['tmp_name'], $audioPath.'/'.$this->sound)) {
Source: GitHub Commit 8cbe660
Detection Methods for CVE-2026-32931
Indicators of Compromise
- Presence of PHP files in the Chamilo audio upload directories (e.g., /app/upload/, document audio paths)
- Web server logs showing requests to .php files within audio/document directories
- Unexpected processes spawned by the www-data user
- POST requests to exercise upload endpoints with suspicious Content-Type headers
Detection Strategies
- Monitor file system for PHP files created in audio/document upload directories using file integrity monitoring (FIM)
- Implement WAF rules to detect file uploads with mismatched Content-Type headers and file extensions
- Review web server access logs for requests to PHP files in unexpected directories
- Deploy endpoint detection to identify webshell behaviors such as command execution, reverse shells, or data exfiltration
Monitoring Recommendations
- Enable detailed logging for file upload operations in Chamilo LMS
- Configure SIEM alerts for new executable files in web-accessible directories
- Monitor for anomalous network connections originating from the web server
- Implement application-level logging to track teacher account activities on exercise-related endpoints
How to Mitigate CVE-2026-32931
Immediate Actions Required
- Upgrade Chamilo LMS to version 1.11.38 or later for the 1.x branch
- Upgrade Chamilo LMS to version 2.0.0-RC.3 or later for the 2.x branch
- Review audio/document upload directories for any unauthorized PHP files
- Temporarily disable teacher file upload capabilities if immediate patching is not possible
- Implement web application firewall rules to block PHP file uploads
Patch Information
The vulnerability is fixed in Chamilo LMS versions 1.11.38 and 2.0.0-RC.3. The fix removes the vulnerable updateSound method entirely from exercise.class.php. Security patches are available through the following commits:
- Commit 8cbe660 - Fix for main branch
- Commit d5ef515 - Fix for public/main branch
For complete vulnerability details, refer to the GitHub Security Advisory GHSA-863j-h6pf-3xhx.
Workarounds
- Restrict teacher account creation and assignment to trusted users only
- Implement web server configuration to prevent PHP execution in upload directories (e.g., php_flag engine off in .htaccess)
- Deploy a web application firewall to inspect and block malicious file uploads
- Use network segmentation to limit potential lateral movement if the web server is compromised
# Apache configuration to prevent PHP execution in upload directories
# Add to .htaccess in the upload directory or virtual host configuration
<Directory "/var/www/chamilo/app/upload">
php_flag engine off
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
</Directory>
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

