CVE-2026-43877
WWBN AVideo: CSRF in userSavePhoto.php Allows Cross-Origin Overwrite of Any Logged-in User's Profile Photo with Arbitrary Bytes
WWBN AVideo is an open source video platform. In versions up to and including 29.0, objects/userSavePhoto.php is a legacy profile-photo endpoint that accepts a base64 POST parameter and writes the decoded bytes to videos/userPhoto/photo<users_id>.png. Its only access control is User::isLogged(). It does not end in .json.php, so it is excluded from the project's global autoCSRFGuard (which is suffix-scoped in objects/include_config.php). There is no CSRF token, no Origin/Referer check, and no MIME validation of the decoded bytes. Because AVideo's default cookie policy is SameSite=None; Secure on HTTPS (objects/functionsPHP.php:227), an attacker who lures a logged-in user to a malicious page can overwrite that user's profile photo with arbitrary bytes and also triggers a site-wide clearCache(true) on every forged request. Commit 9c38468041505e637101c5943c5370c68f48e3ac contains an updated fix.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
5.4
WWBN AVideo: CSRF in userSavePhoto.php Allows Cross-Origin Overwrite of Any Logged-in User's Profile Photo with Arbitrary Bytes
WWBN AVideo is an open source video platform. In versions up to and including 29.0, objects/userSavePhoto.php is a legacy profile-photo endpoint that accepts a base64 POST parameter and writes the decoded bytes to videos/userPhoto/photo<users_id>.png. Its only access control is User::isLogged(). It does not end in .json.php, so it is excluded from the project's global autoCSRFGuard (which is suffix-scoped in objects/include_config.php). There is no CSRF token, no Origin/Referer check, and no MIME validation of the decoded bytes. Because AVideo's default cookie policy is SameSite=None; Secure on HTTPS (objects/functionsPHP.php:227), an attacker who lures a logged-in user to a malicious page can overwrite that user's profile photo with arbitrary bytes and also triggers a site-wide clearCache(true) on every forged request. Commit 9c38468041505e637101c5943c5370c68f48e3ac contains an updated fix.
- Record
CVE-2026-43877- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-352
- Updated
- 2026-11-02
EUVDEUVD-2026-29313
5.4
WWBN AVideo is an open source video platform. In versions up to and including 29.0, objects/userSavePhoto.php is a legacy profile-photo endpoint that accepts a base64 POST parameter and writes the decoded bytes to videos/userPhoto/photo<users_id>.png. Its only access control is User::isLogged(). It does not end in .json.php, so it is excluded from the project's global autoCSRFGuard (which is suffix-scoped in objects/include_config.php). There is no CSRF token, no Origin/Referer check, and no MIME validation of the decoded bytes. Because AVideo's default cookie policy is SameSite=None; Secure on HTTPS (objects/functionsPHP.php:227), an attacker who lures a logged-in user to a malicious page can overwrite that user's profile photo with arbitrary bytes and also triggers a site-wide clearCache(true) on every forged request. Commit 9c38468041505e637101c5943c5370c68f48e3ac contains an updated fix.
- Record
EUVD-2026-29313- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-jw8g-5j46-44rp
5.4
AVideo: CSRF in userSavePhoto.php Allows Cross-Origin Overwrite of Authenticated Users' Profile Photos with Arbitrary Content
Summary
objects/userSavePhoto.php is a legacy profile-photo endpoint that accepts a base64 POST parameter and writes the decoded bytes to videos/userPhoto/photo<users_id>.png. Its only access control is User::isLogged(). It does not end in .json.php, so it is excluded from the project's global autoCSRFGuard (which is suffix-scoped in objects/include_config.php). There is no CSRF token, no Origin/Referer check, and no MIME validation of the decoded bytes. Because AVideo's default cookie policy is SameSite=None; Secure on HTTPS (objects/functionsPHP.php:227), an attacker who lures a logged-in user to a malicious page can overwrite that user's profile photo with arbitrary bytes and also triggers a site-wide clearCache(true) on every forged request.
Details
Handler (objects/userSavePhoto.php, 51 lines total):
// line 12 - only access control
if (!User::isLogged()) {
$obj->msg = __("You must be logged");
die(json_encode($obj));
}
// ...
// line 29 - unvalidated base64 from POST
$fileData = base64DataToImage($_POST['imgBase64']);
// line 30 - deterministic filename tied to the VICTIM's session
$fileName = 'photo'. User::getId().'.png';
$photoURL = $imagePath.$fileName;
// line 35 - raw bytes written to disk
$bytes = file_put_contents($global['systemRootPath'].$photoURL, $fileData);
// lines 43-48 - DB update + global cache invalidation unconditionally
$user = new User(User::getId());
$user->setPhotoURL($photoURL);
if ($user->save()) {
User::deleteOGImage(User::getId());
User::updateSessionInfo();
clearCache(true);
}
base64DataToImage (objects/functionsImages.php:1026) performs no content validation:
function base64DataToImage($imgBase64) {
$img = $imgBase64;
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
return base64_decode($img);
}
There is no call to getimagesizefromstring, imagecreatefromstring, or MIME detection. Arbitrary bytes up to post_max_size are accepted.
Why the global CSRF guard does not apply. objects/include_config.php (around line 314) only invokes autoCSRFGuard when the script filename matches *.json.php:
if (... $_SERVER['REQUEST_METHOD'] === 'POST' &&
substr($baseName, -9) === '.json.php') {
autoCSRFGuard($baseName, $_SERVER['SCRIPT_FILENAME']);
}
userSavePhoto.php is missing the .json.php suffix, so neither autoCSRFGuard nor forbidIfIsUntrustedRequest runs. There is no explicit call to any of these in the file (verified by grep: no getCSRF, no forbidIfIsUntrustedRequest, no HTTP_ORIGIN, no HTTP_REFERER). Routing rewrites in .htaccess also expose this handler as /savePhoto.
Why the victim's cookie is sent cross-origin. objects/functionsPHP.php:227:
function _getCookieSameSiteValue($secure) {
return $secure ? 'None' : 'Lax';
}
On HTTPS (the expected deployment), session cookies default to SameSite=None; Secure, which browsers attach to cross-site POSTs. A plain application/x-www-form-urlencoded form POST is a "simple request" under CORS rules and does not trigger a preflight, so the browser sends the POST and its cookie without the server having to opt in.
PoC
- Victim logs into the AVideo instance (e.g.,
https://victim.example.com).PHPSESSIDis set withSameSite=None; Secure. - Attacker hosts the following HTML on any domain:
<!doctype html>
<html><body>
<form id="f" action="https://victim.example.com/objects/userSavePhoto.php" method="POST">
<!-- Any bytes: here, 'HELLO WORLD' base64-encoded -->
<input name="imgBase64" value="SEVMTE8gV09STEQ=">
</form>
<script>document.forms[0].submit();</script>
</body></html>
- Victim visits the attacker page in the same browser. The form auto-submits. The browser sends the POST with the victim's session cookie.
userSavePhoto.phppasses theUser::isLogged()check, decodes the base64, and writes the raw bytes to…
- Record
GHSA-jw8g-5j46-44rp- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-352
- Updated
- 2026-11-02
NVD
5.4
WWBN AVideo is an open source video platform. In versions up to and including 29.0, objects/userSavePhoto.php is a legacy profile-photo endpoint that accepts a base64 POST parameter and writes the decoded bytes to videos/userPhoto/photo<users_id>.png. Its only access control is User::isLogged(). It does not end in .json.php, so it is excluded from the project's global autoCSRFGuard (which is suffix-scoped in objects/include_config.php). There is no CSRF token, no Origin/Referer check, and no MIME validation of the decoded bytes. Because AVideo's default cookie policy is SameSite=None; Secure on HTTPS (objects/functionsPHP.php:227), an attacker who lures a logged-in user to a malicious page can overwrite that user's profile photo with arbitrary bytes and also triggers a site-wide clearCache(true) on every forged request. Commit 9c38468041505e637101c5943c5370c68f48e3ac contains an updated fix.
- Record
CVE-2026-43877- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-352
- Updated
- 2026-11-02
OSV
5.4
WWBN AVideo: CSRF in userSavePhoto.php Allows Cross-Origin Overwrite of Any Logged-in User's Profile Photo with Arbitrary Bytes
WWBN AVideo is an open source video platform. In versions up to and including 29.0, objects/userSavePhoto.php is a legacy profile-photo endpoint that accepts a base64 POST parameter and writes the decoded bytes to videos/userPhoto/photo<users_id>.png. Its only access control is User::isLogged(). It does not end in .json.php, so it is excluded from the project's global autoCSRFGuard (which is suffix-scoped in objects/include_config.php). There is no CSRF token, no Origin/Referer check, and no MIME validation of the decoded bytes. Because AVideo's default cookie policy is SameSite=None; Secure on HTTPS (objects/functionsPHP.php:227), an attacker who lures a logged-in user to a malicious page can overwrite that user's profile photo with arbitrary bytes and also triggers a site-wide clearCache(true) on every forged request. Commit 9c38468041505e637101c5943c5370c68f48e3ac contains an updated fix.
- Record
CVE-2026-43877- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-352
- Updated
- 2026-11-11
OSVGHSA-jw8g-5j46-44rp
5.4
AVideo: CSRF in userSavePhoto.php Allows Cross-Origin Overwrite of Authenticated Users' Profile Photos with Arbitrary Content
Summary
objects/userSavePhoto.php is a legacy profile-photo endpoint that accepts a base64 POST parameter and writes the decoded bytes to videos/userPhoto/photo<users_id>.png. Its only access control is User::isLogged(). It does not end in .json.php, so it is excluded from the project's global autoCSRFGuard (which is suffix-scoped in objects/include_config.php). There is no CSRF token, no Origin/Referer check, and no MIME validation of the decoded bytes. Because AVideo's default cookie policy is SameSite=None; Secure on HTTPS (objects/functionsPHP.php:227), an attacker who lures a logged-in user to a malicious page can overwrite that user's profile photo with arbitrary bytes and also triggers a site-wide clearCache(true) on every forged request.
Details
Handler (objects/userSavePhoto.php, 51 lines total):
// line 12 - only access control
if (!User::isLogged()) {
$obj->msg = __("You must be logged");
die(json_encode($obj));
}
// ...
// line 29 - unvalidated base64 from POST
$fileData = base64DataToImage($_POST['imgBase64']);
// line 30 - deterministic filename tied to the VICTIM's session
$fileName = 'photo'. User::getId().'.png';
$photoURL = $imagePath.$fileName;
// line 35 - raw bytes written to disk
$bytes = file_put_contents($global['systemRootPath'].$photoURL, $fileData);
// lines 43-48 - DB update + global cache invalidation unconditionally
$user = new User(User::getId());
$user->setPhotoURL($photoURL);
if ($user->save()) {
User::deleteOGImage(User::getId());
User::updateSessionInfo();
clearCache(true);
}
base64DataToImage (objects/functionsImages.php:1026) performs no content validation:
function base64DataToImage($imgBase64) {
$img = $imgBase64;
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
return base64_decode($img);
}
There is no call to getimagesizefromstring, imagecreatefromstring, or MIME detection. Arbitrary bytes up to post_max_size are accepted.
Why the global CSRF guard does not apply. objects/include_config.php (around line 314) only invokes autoCSRFGuard when the script filename matches *.json.php:
if (... $_SERVER['REQUEST_METHOD'] === 'POST' &&
substr($baseName, -9) === '.json.php') {
autoCSRFGuard($baseName, $_SERVER['SCRIPT_FILENAME']);
}
userSavePhoto.php is missing the .json.php suffix, so neither autoCSRFGuard nor forbidIfIsUntrustedRequest runs. There is no explicit call to any of these in the file (verified by grep: no getCSRF, no forbidIfIsUntrustedRequest, no HTTP_ORIGIN, no HTTP_REFERER). Routing rewrites in .htaccess also expose this handler as /savePhoto.
Why the victim's cookie is sent cross-origin. objects/functionsPHP.php:227:
function _getCookieSameSiteValue($secure) {
return $secure ? 'None' : 'Lax';
}
On HTTPS (the expected deployment), session cookies default to SameSite=None; Secure, which browsers attach to cross-site POSTs. A plain application/x-www-form-urlencoded form POST is a "simple request" under CORS rules and does not trigger a preflight, so the browser sends the POST and its cookie without the server having to opt in.
PoC
- Victim logs into the AVideo instance (e.g.,
https://victim.example.com).PHPSESSIDis set withSameSite=None; Secure. - Attacker hosts the following HTML on any domain:
<!doctype html>
<html><body>
<form id="f" action="https://victim.example.com/objects/userSavePhoto.php" method="POST">
<!-- Any bytes: here, 'HELLO WORLD' base64-encoded -->
<input name="imgBase64" value="SEVMTE8gV09STEQ=">
</form>
<script>document.forms[0].submit();</script>
</body></html>
- Victim visits the attacker page in the same browser. The form auto-submits. The browser sends the POST with the victim's session cookie.
userSavePhoto.phppasses theUser::isLogged()check, decodes the base64, and writes the raw bytes to…
- Record
GHSA-jw8g-5j46-44rp- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-352
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
wwbn/avideoPackagist |
through 29.0 | None known |
wwbn/avideoPackagist |
through 29.0, plus listed versions 10.410.81111.111.1.1 Show 12 moreShow less11.511.612.414.314.3.114.418.021.022.024.025.026.0 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-43877 is a medium vulnerability (CVSS 5.4) in Wwbn Avideo, published May 5, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.14%, the 3rd percentile. No source names a fixed version.
References
github.com/WWBN/AVideo/security/advisories/GHSA-jw8g-5j46-44rp
github.com/WWBN/AVideo/commit/9c38468041505e637101c5943c5370c68f48e3ac
nvd.nist.gov/vuln/detail/CVE-2026-43877
github.com/advisories/GHSA-jw8g-5j46-44rp
github.com/CVEProject/cvelistV5/tree/main/cves/2026/43xxx/CVE-2026-43877.json
github.com/WWBN/AVideo
Left out here: the rest of 2 source descriptions. The JSON record has them.