CVE-2026-39369: WWBN AVideo's GIF poster fetch bypasses traversal scrubbing and exposes local files through public media URLs
Summary
objects/aVideoEncoderReceiveImage.json.php allowed an authenticated uploader to fetch attacker-controlled same-origin /videos/... URLs, bypass traversal scrubbing, and expose server-local files through the GIF poster storage path.
The vulnerable GIF branch could be abused to read local files such as /etc/passwd or application source files and republish those bytes through a normal public GIF media URL.
Details
The vulnerable chain was:
1. objects/aVideoEncoderReceiveImage.json.php accepted attacker-controlled downloadURLgifimage 2. traversal scrubbing used strreplace('../', '', ...), which was bypassable with overlapping input such as ....// 3. same-origin /videos/... URLs were accepted 4. urlgetcontents() and trygetcontentsfromlocal() resolved the request into a local filesystem read 5. the fetched bytes were written into the GIF destination 6. invalid GIF cleanup used the wrong variable, so the non-image payload remained on disk
This made the GIF poster path a local file disclosure primitive with public retrieval.
Proof of concept
1. Log in as an uploader and create an owned video row through the normal encoder flow. 2. Send:
text POST /objects/aVideoEncoderReceiveImage.json.php downloadURLgifimage=https://localhost/videos/....//....//....//....//....//....//etc/passwd
3. Query:
text GET /objects/videos.json.php?showAll=1
4. Recover the generated GIF URL from videosURL.gif.url. 5. Download that GIF URL. 6. Observe that the body matches the target local file, such as /etc/passwd, byte-for-byte.
Impact
An authenticated uploader can read server-local files and republish them through a public GIF media URL by supplying a crafted same-origin /videos/... path to downloadURLgifimage. Because traversal scrubbing was bypassable and the fetched bytes were written to the GIF destination without effective invalid-image cleanup, successful exploitation allows disclosure of files such as /etc/passwd, readable application source code, or deployment-specific configuration accessible to the application.
Recommended fix
- Reject any remote image URL whose decoded path contains traversal markers - Do not allow attacker-controlled same-origin /videos/... fetches to resolve into local file reads - Constrain any local shortcut path handling with realpath() and strict base-directory allowlists - Validate GIF content before saving it into public media storage - Ensure invalid-image cleanup checks the correct destination path
Other sources
WWBN AVideo is an open source video platform. In versions 26.0 and prior, objects/aVideoEncoderReceiveImage.json.php allowed an authenticated uploader to fetch attacker-controlled same-origin /videos/... URLs, bypass traversal scrubbing, and expose server-local files through the GIF poster storage path. The vulnerable GIF branch could be abused to read local files such as /etc/passwd or application source files and republish those bytes through a normal public GIF media URL.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
In objects/aVideoEncoderReceiveImage.json.php, do not allow attacker-controlled same-origin `/videos/...` fetches (downloadURL_gifimage) to resolve into local filesystem reads; constrain local shortcut path handling with `realpath()` and strict base-directory allowlists so resolved paths cannot escape the intended `/videos/` base.
objects/aVideoEncoderReceiveImage.json.php (downloadURL_gifimage handling) same-origin /videos/... URL resolution = disallow attacker-controlled same-origin /videos/... fetches that resolve into local file reads - Configuration
Fix traversal scrubbing: the current approach using `str_replace('../', '', ...)` is bypassable with overlapping input such as `....//`. Reject remote image URL inputs whose decoded path contains traversal markers (e.g., sequences indicating traversal) and ensure decoded paths are validated after decoding.
objects/aVideoEncoderReceiveImage.json.php (traversal scrubbing) path traversal scrubbing implementation = replace bypassable traversal scrubbing - Configuration
Ensure invalid-image cleanup checks the correct destination path (the issue described is that invalid-image cleanup used the wrong variable, leaving non-image payload bytes on disk). Validate the destination path variable used for cleanup matches the file actually written to the GIF destination.
GIF invalid-image cleanup in objects/aVideoEncoderReceiveImage.json.php invalid GIF cleanup destination path check = check the correct destination path - Configuration
Validate GIF content before saving it into public media storage; reject payloads that are not valid GIF content so non-image payloads cannot be written to the GIF destination.
GIF processing in objects/aVideoEncoderReceiveImage.json.php GIF content validation before saving = validate GIF content before saving
Event History
Frequently Asked Questions
What is the severity of CVE-2026-39369?
CVE-2026-39369 is considered a medium severity vulnerability that allows exposure of local files.
How do I fix CVE-2026-39369?
To fix CVE-2026-39369, upgrade to AVideo version 26.1 or higher.
Who is affected by CVE-2026-39369?
CVE-2026-39369 affects users of WWBN AVideo versions up to and including 26.0.
What kind of attack does CVE-2026-39369 allow?
CVE-2026-39369 allows an authenticated attacker to bypass traversal scrubbing and access local files through public media URLs.
What files are exposed by CVE-2026-39369?
CVE-2026-39369 exposes local files by allowing access to attacker-controlled URLs through the AVideo application.