Every CVE Search/ Get API key

CVE-2026-45610

WWBN AVideo plugin/LoginControl/set.json.php: 2FA toggle endpoint has no CSRF protection, letting an attacker page silently disable a logged-in victim's 2FA

5.7 Medium

WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a cross-site request forgery vulnerability on the 2FA toggle. plugin/LoginControl/set.json.php accepts POST type=set2FA value=false, calls LoginControl::setUser2FA(User::getId(), false) on the session-authenticated user, and returns. There is no forbidIfIsUntrustedRequest() call, no isTokenValid() check, no X-CSRF-Token/SameSite enforcement, and no re-authentication step. A cross-origin page that the victim visits while logged into the AVideo dashboard issues the POST via a hidden form (or fetch without credentials:"omit") and disables the victim's 2FA in one request.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
Required

What an attacker can affect

Confidentiality
None
Integrity
High
Availability
None

Exploit likelihood

0.11%Up 0.1 points since May 30, 2026
90%50%10%1%

What each source reports

CVE List Score used 5.7

WWBN AVideo plugin/LoginControl/set.json.php: 2FA toggle endpoint has no CSRF protection, letting an attacker page silently disable a logged-in victim's 2FA

WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a cross-site request forgery vulnerability on the 2FA toggle. plugin/LoginControl/set.json.php accepts POST type=set2FA value=false, calls LoginControl::setUser2FA(User::getId(), false) on the session-authenticated user, and returns. There is no forbidIfIsUntrustedRequest() call, no isTokenValid() check, no X-CSRF-Token/SameSite enforcement, and no re-authentication step. A cross-origin page that the victim visits while logged into the AVideo dashboard issues the POST via a hidden form (or fetch without credentials:"omit") and disables the victim's 2FA in one request.

Record
CVE-2026-45610
CVSS 3.1
5.7 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-306, CWE-352
Updated
2026-11-02
EUVDEUVD-2026-33309 5.7

WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a cross-site request forgery vulnerability on the 2FA toggle. plugin/LoginControl/set.json.php accepts POST type=set2FA value=false, calls LoginControl::setUser2FA(User::getId(), false) on the session-authenticated user, and returns. There is no forbidIfIsUntrustedRequest() call, no isTokenValid() check, no X-CSRF-Token/SameSite enforcement, and no re-authentication step. A cross-origin page that the victim visits while logged into the AVideo dashboard issues the POST via a hidden form (or fetch without credentials:"omit") and disables the victim's 2FA in one request.

Record
EUVD-2026-33309
CVSS 3.1
5.7 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-3mv2-vmwh-rwfx 5.7

AVideo: 2FA toggle endpoint has no CSRF protection, letting an attacker page silently disable a logged-in victim's 2FA

Summary

Type: Cross-site request forgery on the 2FA toggle. plugin/LoginControl/set.json.php accepts POST type=set2FA value=false, calls LoginControl::setUser2FA(User::getId(), false) on the session-authenticated user, and returns. There is no forbidIfIsUntrustedRequest() call, no isTokenValid() check, no X-CSRF-Token/SameSite enforcement, and no re-authentication step. A cross-origin page that the victim visits while logged into the AVideo dashboard issues the POST via a hidden form (or fetch without credentials:"omit") and disables the victim's 2FA in one request. The next phishing/credential-stuffing attempt against that account no longer needs the second factor. File: plugin/LoginControl/set.json.php, lines 1-37. Root cause: the developer relied on the User::isLogged() check at line 9 as the only auth, then dispatched directly into LoginControl::setUser2FA(User::getId(), $value=='true'). Other AVideo state-changing endpoints in the same codebase (videoUpdateUsage.json.php, videoStatus.json.php, videoRotate.json.php, etc.) call forbidIfIsUntrustedRequest('<name>') to compare Origin/Referer against the AVideo domain; this endpoint simply omits the call. The session cookie carries the user's identity on every cross-origin POST, so any attacker page can speak for the logged-in user on this endpoint.

Affected Code

File: plugin/LoginControl/set.json.php, lines 1-37.

<?php
require_once '../../videos/configuration.php';
_session_write_close();
header('Content-Type: application/json');

$obj = new stdClass();
$obj->error = true;
$obj->msg = "";
if (!User::isLogged()) {
    $obj->msg = "Not logged";
    die(json_encode($obj));
}
if (empty($_POST['type'])) {
    $obj->msg = "Type is empty";
    die(json_encode($obj));
}
if (!isset($_POST['value'])) {
    $obj->msg = "value is empty";
    die(json_encode($obj));
}

$cu = AVideoPlugin::loadPluginIfEnabled('LoginControl');

if (empty($cu)) {
    $obj->msg = "Plugin not enabled";
    die(json_encode($obj));
}

$obj->error = false;
switch ($_POST['type']) {
    case 'set2FA':
        LoginControl::setUser2FA(User::getId(), $_POST['value']=="true" ? true : false);  // <-- BUG: no CSRF gate, no re-auth
        break;
}

die(json_encode($obj));

Why it's wrong: disabling a victim's second factor is exactly the kind of state change the AVideo CSRF helper forbidIfIsUntrustedRequest() exists to protect. Compare with objects/comments_like.json.php:18 (forbidIfIsUntrustedRequest('comments_like')) — comments-likes get CSRF protection, but the 2FA toggle does not. Beyond CSRF, security-sensitive toggles like 2FA-disable conventionally also require either the current 2FA code or a password re-prompt: a malicious browser extension, an XSS that lands in any AVideo subdomain, or a compromised tab can otherwise flip the bit silently. None of those mitigations exist here.

Exploit Chain

  1. Attacker hosts https://attacker.example/avideo-2fa-off.html containing:
    <form id="f" action="https://avideo.example/plugin/LoginControl/set.json.php" method="POST">
      <input type="hidden" name="type"  value="set2FA">
      <input type="hidden" name="value" value="false">
    </form>
    <script>document.getElementById('f').submit();</script>
    
    State: page is live and indexable.
  2. Attacker delivers the page to a victim who is logged in to avideo.example (open redirect on a trusted partner, ad campaign, IM phishing link, encyclopedic-looking forum post). The victim's browser opens the page; the form auto-submits to AVideo. State: cross-origin POST hits set.json.php with the victim's session cookie attached (the cookie's SameSite attribute is set to Lax/None by AVideo's defaults so the cross-origin POST succeeds for top-level navigations).
  3. set.json.php:9 confirms User::isLogged() (true, victim's session is valid). Lines 13-19 see type=set2FA, value=false. Line 30-32 calls…
Record
GHSA-3mv2-vmwh-rwfx
CVSS 3.1
5.7 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-306, CWE-352
Updated
2026-11-02
NVD 5.7

WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a cross-site request forgery vulnerability on the 2FA toggle. plugin/LoginControl/set.json.php accepts POST type=set2FA value=false, calls LoginControl::setUser2FA(User::getId(), false) on the session-authenticated user, and returns. There is no forbidIfIsUntrustedRequest() call, no isTokenValid() check, no X-CSRF-Token/SameSite enforcement, and no re-authentication step. A cross-origin page that the victim visits while logged into the AVideo dashboard issues the POST via a hidden form (or fetch without credentials:"omit") and disables the victim's 2FA in one request.

Record
CVE-2026-45610
CVSS 3.1
5.7 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-306, CWE-352
Updated
2026-11-02
OSV 5.7

WWBN AVideo plugin/LoginControl/set.json.php: 2FA toggle endpoint has no CSRF protection, letting an attacker page silently disable a logged-in victim's 2FA

WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a cross-site request forgery vulnerability on the 2FA toggle. plugin/LoginControl/set.json.php accepts POST type=set2FA value=false, calls LoginControl::setUser2FA(User::getId(), false) on the session-authenticated user, and returns. There is no forbidIfIsUntrustedRequest() call, no isTokenValid() check, no X-CSRF-Token/SameSite enforcement, and no re-authentication step. A cross-origin page that the victim visits while logged into the AVideo dashboard issues the POST via a hidden form (or fetch without credentials:"omit") and disables the victim's 2FA in one request.

Record
CVE-2026-45610
CVSS 3.1
5.7 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-306, CWE-352
Updated
2026-11-02
OSVGHSA-3mv2-vmwh-rwfx 5.7

AVideo: 2FA toggle endpoint has no CSRF protection, letting an attacker page silently disable a logged-in victim's 2FA

Summary

Type: Cross-site request forgery on the 2FA toggle. plugin/LoginControl/set.json.php accepts POST type=set2FA value=false, calls LoginControl::setUser2FA(User::getId(), false) on the session-authenticated user, and returns. There is no forbidIfIsUntrustedRequest() call, no isTokenValid() check, no X-CSRF-Token/SameSite enforcement, and no re-authentication step. A cross-origin page that the victim visits while logged into the AVideo dashboard issues the POST via a hidden form (or fetch without credentials:"omit") and disables the victim's 2FA in one request. The next phishing/credential-stuffing attempt against that account no longer needs the second factor. File: plugin/LoginControl/set.json.php, lines 1-37. Root cause: the developer relied on the User::isLogged() check at line 9 as the only auth, then dispatched directly into LoginControl::setUser2FA(User::getId(), $value=='true'). Other AVideo state-changing endpoints in the same codebase (videoUpdateUsage.json.php, videoStatus.json.php, videoRotate.json.php, etc.) call forbidIfIsUntrustedRequest('<name>') to compare Origin/Referer against the AVideo domain; this endpoint simply omits the call. The session cookie carries the user's identity on every cross-origin POST, so any attacker page can speak for the logged-in user on this endpoint.

Affected Code

File: plugin/LoginControl/set.json.php, lines 1-37.

<?php
require_once '../../videos/configuration.php';
_session_write_close();
header('Content-Type: application/json');

$obj = new stdClass();
$obj->error = true;
$obj->msg = "";
if (!User::isLogged()) {
    $obj->msg = "Not logged";
    die(json_encode($obj));
}
if (empty($_POST['type'])) {
    $obj->msg = "Type is empty";
    die(json_encode($obj));
}
if (!isset($_POST['value'])) {
    $obj->msg = "value is empty";
    die(json_encode($obj));
}

$cu = AVideoPlugin::loadPluginIfEnabled('LoginControl');

if (empty($cu)) {
    $obj->msg = "Plugin not enabled";
    die(json_encode($obj));
}

$obj->error = false;
switch ($_POST['type']) {
    case 'set2FA':
        LoginControl::setUser2FA(User::getId(), $_POST['value']=="true" ? true : false);  // <-- BUG: no CSRF gate, no re-auth
        break;
}

die(json_encode($obj));

Why it's wrong: disabling a victim's second factor is exactly the kind of state change the AVideo CSRF helper forbidIfIsUntrustedRequest() exists to protect. Compare with objects/comments_like.json.php:18 (forbidIfIsUntrustedRequest('comments_like')) — comments-likes get CSRF protection, but the 2FA toggle does not. Beyond CSRF, security-sensitive toggles like 2FA-disable conventionally also require either the current 2FA code or a password re-prompt: a malicious browser extension, an XSS that lands in any AVideo subdomain, or a compromised tab can otherwise flip the bit silently. None of those mitigations exist here.

Exploit Chain

  1. Attacker hosts https://attacker.example/avideo-2fa-off.html containing:
    <form id="f" action="https://avideo.example/plugin/LoginControl/set.json.php" method="POST">
      <input type="hidden" name="type"  value="set2FA">
      <input type="hidden" name="value" value="false">
    </form>
    <script>document.getElementById('f').submit();</script>
    
    State: page is live and indexable.
  2. Attacker delivers the page to a victim who is logged in to avideo.example (open redirect on a trusted partner, ad campaign, IM phishing link, encyclopedic-looking forum post). The victim's browser opens the page; the form auto-submits to AVideo. State: cross-origin POST hits set.json.php with the victim's session cookie attached (the cookie's SameSite attribute is set to Lax/None by AVideo's defaults so the cross-origin POST succeeds for top-level navigations).
  3. set.json.php:9 confirms User::isLogged() (true, victim's session is valid). Lines 13-19 see type=set2FA, value=false. Line 30-32 calls…
Record
GHSA-3mv2-vmwh-rwfx
CVSS 3.1
5.7 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-306, CWE-352
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
WWBN/AVideo
Packagist
through 29.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-45610 is a medium vulnerability (CVSS 5.7) in Wwbn Avideo, published May 15, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.11%, the 1st 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