ANT-2026-XBE9HJ4Y · moodle/moodle
path-traversal high
Severity Claude high · Security research firm high · Maintainer -
Discovered by Claude Mythos Preview
Anthropic's analysis, sealed at approval. Disclosure to the maintainer was performed by Ophion Security.
ANT-2026-XBE9HJ4Y: Path Traversal → Arbitrary File Write → RCE in repository_googledocs
repository_googledocs::download_file() passes the Google Drive file name (fetched from the Google API and therefore controlled by the file owner) directly to repository::prepare_file(), which performs a naive string concatenation with no path sanitization. The resulting path is opened with fopen(..., 'w') by curl::download_one().
An authenticated Moodle user (student or teacher) who links their Google account can create a Google Drive file named ../../../../../../../../var/www/html/public/shell.php, pick it as an Access Controlled Link, and submit the form. When Moodle processes the draft → final transition it fetches the file's name from Google, builds a temp path with it, and writes the attacker's file body to that path — escaping the temp directory and landing a PHP web-shell in the Moodle web-root.
Google Drive uses a flat namespace where name is arbitrary metadata; the / character is fully permitted in Drive file names.
Target
Project: moodle/moodle
Commit: 9a5df8d6da29571e
Discovery: static analysis — not yet dynamically reproduced
Technical Details
Root cause is trusting the externally-supplied name field from the Google Drive v3 files API as a safe local path component. prepare_file() performs naive string concatenation with no '..'/'/'/null-byte stripping, and download_one() calls fopen($options['filepath'], 'w') directly, which follows traversal sequences and creates/truncates the target. Although Moodle HMAC-validates the Drive file ID via sourcekey, the name is re-fetched at commit time and never validated, so attacker-chosen traversal sequences survive to the fopen sink.
Reproduction
This finding was identified by static analysis and has not yet been dynamically reproduced. The Technical Details section above describes the code path; a trigger input is not included.
[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]
Acknowledgement
This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-XBE9HJ4Y.
Reference: ANT-2026-XBE9HJ4Y
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure
Triage and disclosure were performed by Ophion Security.
- Verdict
- true positive
- Severity
- high
Recorded dates, in order.
- 2026-03-30 Discovered or logged
- 2026-04-10 Maintainer acknowledged
- 2026-04-23 Sent to maintainer
- 2026-05-18 Patch released
- 2026-07-21 Publicly revealed
SHA-3-512 hash:
abdda0ccd741fe8be1684c7434f523327ddb872f9e7acb72e2f95f687850e08db5ae5f2c1d6df22ff433676f6dafa86f2060d13be74b09eeda5b2a0b1c897283
Committed 2026-04-23 07:04 UTC
Revealed 2026-07-21 05:10 UTC
Verify (download preimage.json)
Show preimage JSON
{
"ant_id": "ANT-2026-XBE9HJ4Y",
"bug_class": "Path-traversal",
"claude_severity": "high",
"commit_sha": "9a5df8d6da29571e",
"created_at": "2026-03-30T23:20:07+00:00",
"description": "`repository_googledocs::download_file()` passes the Google Drive file **name** (fetched from the Google API and therefore controlled by the file owner) directly to `repository::prepare_file()`, which performs a naive string concatenation with no path sanitization. The resulting path is opened with `fopen(..., 'w')` by `curl::download_one()`.\n\nAn authenticated Moodle user (student or teacher) who links their Google account can create a Google Drive file named `../../../../../../../../var/www/html/public/shell.php`, pick it as an **Access Controlled Link**, and submit the form. When Moodle processes the draft → final transition it fetches the file's name from Google, builds a temp path with it, and writes the attacker's file body to that path — escaping the temp directory and landing a PHP web-shell in the Moodle web-root.\n\nGoogle Drive uses a flat namespace where `name` is arbitrary metadata; the `/` character is fully permitted in Drive file names.",
"discovered_at": null,
"location": null,
"poc_sha256": "e85b8dd500756df02a336874b983832d929bce2409b55f4484b99481743e405f",
"preimage_version": 1,
"project": "moodle",
"reproduction": null,
"technical_details": "Root cause is trusting the externally-supplied `name` field from the Google Drive v3 files API as a safe local path component. prepare_file() performs naive string concatenation with no '..'/'/'/null-byte stripping, and download_one() calls fopen($options['filepath'], 'w') directly, which follows traversal sequences and creates/truncates the target. Although Moodle HMAC-validates the Drive file *ID* via sourcekey, the *name* is re-fetched at commit time and never validated, so attacker-chosen traversal sequences survive to the fopen sink.",
"title": "Path Traversal → Arbitrary File Write → RCE in repository_googledocs",
"vendor_severity": "high"
}