AVideo: 2FA toggle endpoint has no CSRF protection, letting an attacker page silently disable a logged-in victim's 2FA
Date: 2026-05
Affected: composer/WWBN/AVideo
Attack vector: path-traversal
Category: vulnerability-disclosure
Severity: Medium
CVE: CVE-2026-45610
CWE: CWE-306
CWE-352
CVSS: 5.7 (CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N)

## 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 <?php require_once '../../videos/configura


Mitigations:

Architectural layers (MAESTRO):