Summary
plugin/MobileManager/oauth2.php completes an OAuth login by sending an HTTP 302 Location: oauth2Success.php?user=<email>&pass=<HASH> where <HASH> is the victim's stored password hash (md5(hash("whirlpool", sha1(password)))) read directly from the users table. AVideo's own login endpoint (objects/login.json.php) accepts an encodedPass=1 flag that bypasses hashing and performs a direct string comparison between the supplied value and the stored hash. Anyone who captures the redirect URL, via server logs, referrer leakage, or browser history, therefore obtains a credential equivalent to the plaintext password and can fully take over the account, including admin accounts.
Details
Sink: hash inlined in a GET redirect
plugin/MobileManager/oauth2.php:98-102:
$pass = rand();
$users_id = User::createUserIfNotExists($user, $pass, $name, $email, $photoURL);
$adapter->disconnect();
$userObject = new User($users_id);
header("Location: oauth2Success.php?user=" . $userObject->getUser() . "&pass=" . $userObject->getPassword());
$userObject->getPassword() returns the raw database column (objects/user.php:159-162):
public function getPassword()
{
return strip_tags($this->password);
}
The returned value is the stored password hash for the account (existing or freshly-created). It is transported to the browser as a query-string parameter in the Location: header, so it is written to:
- Web-server access logs (
combined/mainlog formats record the full request line including query string). - Upstream proxy / CDN / WAF logs.
- Any error monitoring / APM that captures request URLs (Sentry, Datadog, New Relic defaults).
- The victim's browser history (persistent local artifact).
- The
Refererheader on subsequent navigation from the renderedoauth2Success.phppage if the page or its assets load any external origin and the browser'sReferrer-Policyis not strict.
Hash equals plaintext for login
objects/login.json.php:182-209:
if (!empty($_GET['user'])) {
$_POST['user'] = $_GET['user'];
}
if (!empty($_GET['pass'])) {
$_POST['pass'] = $_GET['pass'];
}
if (!empty($_GET['encodedPass'])) {
$_POST['encodedPass'] = $_GET['encodedPass'];
}
...
$user = new User(0, $_POST['user'], $_POST['pass']);
...
$resp = $user->login(false, @$_POST['encodedPass']);
objects/user.php:1272-1279 passes $encodedPass to find():
if (strtolower($encodedPass) === 'false') {
$encodedPass = false;
}
...
$user = $this->find($this->user, $this->password, true, $encodedPass);
objects/user.php:1785-1794:
if ($pass !== false) {
if (!encryptPasswordVerify($pass, $result['password'], $encodedPass)) {
...
return false;
}
}
objects/functions.php:2312-2331:
function encryptPasswordVerify(#[\SensitiveParameter] $password, $hash, $encodedPass = false)
{
global $advancedCustom, $global;
if (!$encodedPass || $encodedPass === 'false') {
$passwordSalted = encryptPassword($password);
$passwordUnSalted = encryptPassword($password, true);
} else {
$passwordSalted = $password; // <- direct use, no hashing
$passwordUnSalted = $password;
}
$isValid = $passwordSalted === $hash || $passwordUnSalted === $hash;
...
}
When encodedPass is truthy, the supplied value is compared as-is against the stored hash. The captured redirect parameter pass=<HASH> is therefore a valid login credential when replayed with encodedPass=1.
Compounding factors
- The redirect is a raw
Location:(GET), not a POST, the secret is placed in a URL which is by definition non-confidential transport. - No CSRF token, no
stateparameter tied to the session, and no single-use token is used on/plugin/MobileManager/oauth2.php. login.json.phpdoes not require a CSRF token or captcha on the first attempt (checkLoginAttempts()atobjects/user.php:1282only rate-limits after failures, and the attacker succeeds on the first try).- By contrast, the non-plugin flow in
objects/login.json.php:144-145already sets session state server-side ($userObject->login(true)), demonstrating the project already has a safer pattern available.
PoC
Prerequisites: MobileManager plugin enabled and at least one supported login provider (e.g. LoginGoogle) configured with valid keys, both are common production settings for this product.
Victim initiates the mobile OAuth flow:
GET /plugin/MobileManager/oauth2.php?type=GoogleAfter the victim authorizes at the provider, the server sends:
HTTP/1.1 302 Found Location: oauth2Success.php?user=victim%40example.com&pass=9d7ab4...stored-hash...This request-line, including the password hash, is written to the web server's access log (default
combinedformat) and to any upstream proxy/CDN log. It also appears in the victim's browser history.Attacker obtains
<HASH>from any of those channels.Attacker logs in as the victim without knowing the plaintext password:
curl -i -c cookies.txt \ 'https://target.example.com/objects/[email protected]&pass=<HASH>&encodedPass=1'Expected response:
200 OKwith JSON containingid,user,PHPSESSID,isAdmin,email, and aSet-Cookie: PHPSESSID=...that grants full account access. The attacker can now browse, upload, modify the victim's channel, or, if the victim is an admin, access/mvideosand all admin endpoints.
Impact
- Full account takeover of any user who has ever logged in through the MobileManager OAuth endpoint.
- If the victim is an administrator, the attacker gains administrative control of the AVideo instance (user management, plugin config, site-wide content).
- The exposed hash works indefinitely: it remains valid for as long as the victim does not change their password, so a one-time log/history/referrer capture yields a persistent credential.
- Passes silently, from the application's perspective, the attacker is just a legitimate login with
encodedPass=1(a flag the product itself uses for mobile-app "remember me" flows).
CVE-2026-43875 has a CVSS score of 6.8 (Medium). The vector is network-reachable, no privileges required, and user interaction required. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. No fixed version is listed yet, so configuration controls and monitoring matter more in the interim.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Remediation advice
Never place the password hash (or any credential-equivalent material) in a URL. In
plugin/MobileManager/oauth2.php, mirror whatobjects/login.json.php:143-146already does for the web flow, establish the session server-side and redirect to a URL with no credentials:$userObject = new User(0, $user, $pass); $userObject->login(true); // server-side session header("Location: oauth2Success.php");Additionally, remove or hard-restrict the
encodedPassbranch inobjects/functions.php:2319-2329. If a "hash-equivalent" credential must exist for the mobile app, replace it with a short-lived, single-use, server-issued bearer token bound to the session, rather than the persistent database hash.Add a
stateparameter and CSRF protection on/plugin/MobileManager/oauth2.phpso the redirect cannot be initiated from a third-party origin.For defense-in-depth, strip query strings containing
pass=from access-log formats and ensureoauth2Success.phpsetsReferrer-Policy: no-referrerwhile it is being deprecated.
Frequently Asked Questions
- What is CVE-2026-43875? CVE-2026-43875 is a medium-severity security vulnerability in wwbn/avideo (composer), affecting versions <= 29.0. No fixed version is listed yet.
- How severe is CVE-2026-43875? CVE-2026-43875 has a CVSS score of 6.8 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of wwbn/avideo are affected by CVE-2026-43875? wwbn/avideo (composer) versions <= 29.0 is affected.
- Is there a fix for CVE-2026-43875? No fixed version is listed for CVE-2026-43875 yet. Monitor the advisory for updates and apply mitigations in the interim.
- Is CVE-2026-43875 exploitable, and should I be worried? Whether CVE-2026-43875 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-43875 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.