GHSA-m9h6-8pqm-xrhf Admidio has Path Traversal via Unvalidated `name` Parameter in Document Add Mode that Enables Arbitrary Server File Read
SummaryThe `add` mode in `modules/documents-files.php` accepts a `name` parameter validated only as `'string'` type (HTML encoding), allowing path traversal characters (`../`) to pass through unfiltered. Combined with the absence of CSRF protection on this endpoint and `SameSite=Lax` session cookies, a low-privileged attacker can trick a documents administrator into clicking a crafted link that registers an arbitrary server file (e.g., `install/config.php` containing database credentials) into a documents folder accessible to the attacker.Details**Root cause — incorrect input validation type (modules/documents-files.php:222):**The `'string'` type in `admFuncVariableIsValid()` only applies `SecurityUtils::encodeHTML(StringUtils::strStripTags($value))` (system/bootstrap/function.php:414-416). Since `../` contains no HTML special characters (`<`, `>`, `&`, `"`, `'`), path traversal sequences pass through unchanged.The correct type would be `'file'`, which calls `StringUtils::strIsValidFileName()` (src/Infrastructure/Utils/StringUtils.php:217-236). This function checks `basename($filename) !== $filename` at line 228, which would reject any path containing directory separators.**Missing CSRF protection (modules/documents-files.php:221-238):**No `SecurityUtils::validateCsrfToken()` or form object validation. Compare with `folder_delete` (line 140) and `file_delete` (line 170) which both validate CSRF tokens. The `add` action operates entirely via GET parameters.**Unsafe path construction (src/Documents/Entity/Folder.php:121-135):**No `realpath()` comparison or `basename()` check. The traversal filename (e.g., `../../../install/config.php`) is stored verbatim as `fil_name` in the database.**File served on download (src/Documents/Entity/File.php:88-91, src/Documents/Service/DocumentsService.php:68-119):****SameSite=Lax allows cross-site GET (src/Session/Entity/Session.php:544):**Top-level GET navigations from cross-site origins include the session cookie, enabling the CSRF attack vector.PoC**Prerequisites:** Attacker has a regular user account with access to the documents module. A documents administrator is available to be social-engineered.Impact**Arbitrary server file read**: An attacker can read any file on the server that the web server process has read access to, including `install/config.php` (database credentials), `/etc/passwd`, application source code, and other configuration files.**Database credential exposure**: The primary target `install/config.php` contains plaintext database credentials, enabling direct database access and full compromise of the Admidio installation.**Low attack complexity**: The CSRF vector requires only that an admin clicks a single link — no JavaScript, no form submission, no special browser behavior.Recommended Fix**Fix 1 — Use `'file'` validation type for the `name` parameter (modules/documents-files.php:222):**This invokes `StringUtils::strIsValidFileName()` which checks `basename($filename) !== $filename` and rejects any path containing directory traversal.**Fix 2 — Add CSRF protection to the `add` mode (modules/documents-files.php:221-238):**Change the `add` action from GET to POST and add CSRF token validation:**Fix 3 (defense in depth) — Add path canonicalization in `addFolderOrFileToDatabase()` (src/Documents/Entity/Folder.php):**All three fixes should be applied for defense in depth.
CVSS v3.1 score: 4.5