Every CVE Search/ Get API key

CVE-2026-43875

WWBN AVideo: Password Hash Leaked in MobileManager OAuth Redirect URL Enables Account Takeover

6.8 Medium

WWBN AVideo is an open source video platform. In versions up to and including 29.0, 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. Commit 977cd6930a97571a26da4239e25c8096dd4ecbc1 contains an updated fix.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
None
User interaction
Required

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Exploit likelihood

0.33%Up 0.3 points since May 12, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.8

WWBN AVideo: Password Hash Leaked in MobileManager OAuth Redirect URL Enables Account Takeover

WWBN AVideo is an open source video platform. In versions up to and including 29.0, 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. Commit 977cd6930a97571a26da4239e25c8096dd4ecbc1 contains an updated fix.

Record
CVE-2026-43875
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-598
Updated
2026-11-02
EUVDEUVD-2026-29311 6.8

WWBN AVideo is an open source video platform. In versions up to and including 29.0, 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. Commit 977cd6930a97571a26da4239e25c8096dd4ecbc1 contains an updated fix.

Record
EUVD-2026-29311
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-5w8w-26ch-v5cw 6.8

AVideo: Password Hash Leak in MobileManager OAuth Redirect URL Enables Account Takeover

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 / main log 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 Referer header on subsequent navigation from the rendered oauth2Success.php page if the page or its assets load any external origin and the browser's Referrer-Policy is 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 state parameter tied to the session, and no single-use token is used on /plugin/MobileManager/oauth2.php.
  • login.json.php does not require a CSRF token or captcha on the first attempt (checkLoginAttempts() at objects/user.php:1282 only…
Record
GHSA-5w8w-26ch-v5cw
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-598
Updated
2026-11-02
NVD 6.8

WWBN AVideo is an open source video platform. In versions up to and including 29.0, 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. Commit 977cd6930a97571a26da4239e25c8096dd4ecbc1 contains an updated fix.

Record
CVE-2026-43875
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-598
Updated
2026-11-02
OSV 6.8

WWBN AVideo: Password Hash Leaked in MobileManager OAuth Redirect URL Enables Account Takeover

WWBN AVideo is an open source video platform. In versions up to and including 29.0, 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. Commit 977cd6930a97571a26da4239e25c8096dd4ecbc1 contains an updated fix.

Record
CVE-2026-43875
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-598
Updated
2026-11-02
OSVGHSA-5w8w-26ch-v5cw 6.8

AVideo: Password Hash Leak in MobileManager OAuth Redirect URL Enables Account Takeover

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 / main log 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 Referer header on subsequent navigation from the rendered oauth2Success.php page if the page or its assets load any external origin and the browser's Referrer-Policy is 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 state parameter tied to the session, and no single-use token is used on /plugin/MobileManager/oauth2.php.
  • login.json.php does not require a CSRF token or captcha on the first attempt (checkLoginAttempts() at objects/user.php:1282 only…
Record
GHSA-5w8w-26ch-v5cw
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-598
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
wwbn/avideo
Packagist
through 29.0 None known
wwbn/avideo
Packagist
through 29.0, plus listed versions
10.410.81111.111.1.1
Show 12 moreShow less
11.511.612.414.314.3.114.418.021.022.024.025.026.0
None known

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-43875 is a medium vulnerability (CVSS 6.8) 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.33%, the 26th percentile. No source names a fixed version.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open