Jan 24, 2026·6 min read·90 visits
Moodle's course restore feature blindly trusts parts of the backup archive structure. An attacker with 'Teacher' privileges can upload a crafted `.mbz` backup file containing malicious payloads. When Moodle parses this file to restore the course, it triggers arbitrary code execution, handing the attacker a shell with web server privileges.
A critical Remote Code Execution vulnerability in Moodle's core backup/restore functionality allows authenticated users (like Teachers) to compromise the entire server by uploading malicious course archives.
In the world of web security, file uploads are the "Check Engine" light that you've been ignoring for three years. You know it's going to be a problem, you just don't know when the engine block is going to melt. Moodle, the behemoth of Learning Management Systems (LMS), relies heavily on a feature called "Course Restore." It allows educators to move courses between sites or restore backups. It sounds mundane, but technically, it is a minefield.
The process involves taking a compressed archive (.mbz), unzipping it, parsing a labyrinth of XML configuration files, and reconstructing complex PHP objects and database entries. It is essentially a deserialization bomb waiting to go off. The developers assumed that because the feature requires authentication (usually a Teacher or Admin role), the input would be benevolent. That assumption is what we in the industry call "optimistic," and what hackers call "an open invitation."
CVE-2025-67847 isn't just a bug; it's a fundamental flaw in trust. Moodle treats the contents of a backup file—which is just user-controlled input wrapped in a ZIP—as a set of instructions to follow blindly. When you let a user write instructions for your server to execute, you shouldn't be surprised when they instruct it to open a reverse shell.
The vulnerability lives deep within the core_backup and core_restore subsystems. When Moodle restores a course, it reads XML files (like moodle_backup.xml) that define everything from course settings to file references. The flaw specifically is an Improper Control of Generation of Code (CWE-94).
Here is the breakdown: The restore engine reads values from the XML and, in certain edge cases, uses them to dynamically instantiate classes or execute logic to rebuild the course state. If the sanitization is lazy—or nonexistent—an attacker can inject data that Moodle doesn't just store, but acts upon.
The specific vector here involves Moodle parsing serialized PHP objects or improperly validated XML elements that trigger magic methods. PHP's unserialize() is notorious for this, but even without direct unserialization, if the application takes a string from the XML and uses it in a call_user_func() or a dynamic class instantiation context without a strict allowlist, you achieve Code Injection. In this case, the restore routine fails to verify that the data being processed matches the expected data types before passing them to sensitive internal functions.
While the exact diff is protected to prevent mass exploitation of unpatched systems, the vulnerability pattern is classic. Imagine a simplified version of the restore logic. The vulnerable code likely looked something like this, iterating over XML nodes and dynamically handling them:
// VULNERABLE LOGIC (Conceptual)
$data = $xml_parser->get_next_element();
// The code blindly trusts the 'handler' class specified in the backup
if (isset($data['handler_class'])) {
$handler = new $data['handler_class']($data['params']);
$handler->execute();
}In the code above, if an attacker controls $data['handler_class'], they can instantiate any class available in the Moodle autoloader. If they find a class with a destructor or a constructor that performs file operations (a "gadget"), they win.
The fix involves enforcing strict type checking and allow-listing. The patched version likely introduces a validation layer that checks the class name against a hardcoded list of allowed restore handlers before instantiation:
// PATCHED LOGIC (Conceptual)
$allowed_handlers = ['restore_structure_step', 'restore_dbops'];
$handler_class = $data['handler_class'];
if (!in_array($handler_class, $allowed_handlers, true)) {
throw new restore_exception('Invalid handler detected');
}
// Safe to instantiate now
$handler = new $handler_class($data['params']);By moving from an implicit trust model ("run whatever the file says") to an explicit trust model ("only run what we know is safe"), the RCE vector is closed.
Exploiting this requires an authenticated user account, but don't let that lower the severity score. In a university setting, "Teacher" accounts are handed out to thousands of adjuncts, TAs, and staff. Compromising one weak password gives you the keys to the kingdom.
Step 1: The Payload. The attacker creates a valid-looking Moodle backup. They can start by exporting a legitimate empty course.
Step 2: The Injection. They unzip the .mbz file and modify moodle_backup.xml. They locate the section responsible for defining restore steps or file handlers. They inject a PHP Object Injection payload or a malicious class definition designed to trigger a system command (e.g., system('id')) upon instantiation.
Step 3: The Delivery. The attacker logs in as the compromised Teacher, navigates to Course Administration > Restore, and uploads the evil.mbz file.
Step 4: Detonation. The moment the "Restore" button is clicked, Moodle's backend process (often running as www-data) parses the XML. It hits the malicious tag, instantiates the gadget, and executes the command. The attacker now has a reverse shell. From there, they can dump the mdl_user table, change grades, or pivot to the internal LDAP server.
This is a CVSS 8.8 High severity issue, and frankly, that might be conservative depending on your environment. The impact is total confidentiality, integrity, and availability loss.
Data Theft: Moodle databases are treasure troves. Student PII, home addresses, grades, and sometimes payment information. A shell on the web server usually implies read access to config.php, which contains the cleartext database credentials.
Ransomware: educational institutions are prime targets for ransomware. With RCE, an attacker can encrypt the course materials and the database, effectively shutting down the university's ability to operate.
Academic Integrity: Imagine the chaos if a hacker subtly altered grades across the board. The trust in the institution would be shattered irrevocably. This isn't just a technical glitch; it's an existential threat to the organization's reputation.
If you are running Moodle 5.1.0, 5.0.x, or older branches like 4.5.x/4.1.x, you are vulnerable. The remediation is straightforward but urgent.
1. Patch Immediately: Update to versions 5.1.1, 5.0.4, 4.5.8, 4.4.12, or 4.1.22. Moodle has backported the fix to LTS versions, so you have no excuse to stay on insecure code.
2. Least Privilege: Why does every adjunct professor need the ability to restore course backups? Review your roles. Remove the moodle/restore:restorecourse capability from the standard Teacher role and create a specialized "Course Creator" role for the few who actually need it.
3. Monitoring: Set up alerts for the creation of restore processes in your logs, specifically looking for failures or anomalies in the restore log files. If a restore fails with a "class not found" or "serialization error," investigate immediately—it might be a failed exploit attempt.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Moodle Moodle | = 5.1.0 | 5.1.1 |
Moodle Moodle | >= 5.0.0, <= 5.0.3 | 5.0.4 |
Moodle Moodle | >= 4.5.0, <= 4.5.7 | 4.5.8 |
Moodle Moodle | >= 4.1.0, <= 4.1.21 | 4.1.22 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-94 (Code Injection) |
| CVSS Score | 8.8 (High) |
| Attack Vector | Network (Authenticated) |
| Attack Complexity | Low |
| Privileges Required | Low (e.g., Teacher) |
| Impact | Confidentiality, Integrity, Availability (High) |
The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVE-2026-5038 is a critical denial of service vulnerability in the Node.js Multer middleware. When utilizing the diskStorage engine, connection termination or validation failures leave partial files orphaned on the local filesystem due to stream-destruction signal propagation failures in Node's piping mechanism. Remote unauthenticated attackers can exploit this to fill server disks and induce system crashes.
CVE-2026-5079 is a high-severity Denial of Service (DoS) vulnerability in the Node.js package 'multer'. The vulnerability resides in how its internal dependency, 'append-field', processes deeply nested bracket structures in multipart form field names. If an attacker submits a field name with an excessive number of nested brackets, the parsing process crashes the Node.js runtime environment or exhausts system resources, causing a complete denial of service.
webpack-dev-server (WDS) is vulnerable to an Origin Validation Error (CWE-346) and a Confused Deputy vulnerability (CWE-441) due to path normalization discrepancies in its upgrade handling. When a proxy is configured with a broad context and WebSocket support is enabled, the proxy middleware intercepts internal Hot Module Replacement (HMR) WebSocket upgrade requests. This forwards the browser's credentials (such as Cookies and Origin headers) to the backend target, bypassing built-in security controls and corrupting the WebSocket connection.
An information disclosure vulnerability exists in OpenClaw before version 2026.5.12. The issue resides within the streamable-http Model Context Protocol (MCP) server integration, where the application client automatically forwards operator-configured custom headers during cross-origin HTTP redirects. If an attacker controls or compromises a configured remote MCP endpoint, they can issue redirect responses to exfiltrate highly sensitive data, such as API keys or tenant-routing credentials, to unauthorized external origins.
A critical preprocessing mismatch exists in vLLM's multimodal image pipeline before commit cf1c90672404548aa3bc51f92c4745576a65ee26. The vulnerability occurs because the engine loads user-submitted images and passes them to underlying Vision-Language Models (VLMs) without normalizing their EXIF orientation metadata or fully resolving complex transparency structures. This gap creates a perception desynchronization vulnerability where the physical pixel grid processed by the AI model differs significantly from how the image is visually rendered to human moderators or frontend applications. Attackers can exploit this mismatch to perform silent prompt injections, bypass safety moderation systems, or execute adversarial jailbreaks.
An incorrect authorization vulnerability exists in the open-source workflow automation platform n8n within the Evaluation Test Runs Controller. In deployments utilizing Advanced Permissions, an authenticated user assigned a low-privilege project:viewer role can bypass configured permission policies. This allows the unauthorized user to execute, terminate, or delete workflow evaluation test runs by exploiting misconfigured API scope validations that map read-only scopes to mutating endpoints.