GHSA-ff5q-cc22-fgp4: WWBN AVideo has a CORS Origin Reflection Bypass via plugin/API/router.php and allowOrigin(true) Exposes Authenticated API Responses
SummaryThe CORS origin validation fix in commit `986e64aad` is incomplete. Two separate code paths still reflect arbitrary `Origin` headers with credentials allowed for all `/api/*` endpoints: (1) `plugin/API/router.php` lines 4-8 unconditionally reflect any origin before application code runs, and (2) `allowOrigin(true)` called by `get.json.php` and `set.json.php` reflects any origin with `Access-Control-Allow-Credentials: true`. An attacker can make cross-origin credentialed requests to any API endpoint and read authenticated responses containing user PII, email, admin status, and session-sensitive data.DetailsBypass Vector 1: router.php independent CORS handler`plugin/API/router.php:4-8` runs before any application code:This reflects **any** `Origin` header verbatim. For OPTIONS preflight requests (lines 14-18), the script exits immediately — the fixed `allowOrigin()` function never executes:All `/api/*` requests are routed through this file via `.htaccess` rules (lines 131-132).Bypass Vector 2: allowOrigin($allowAll=true)Both `plugin/API/get.json.php:12` and `plugin/API/set.json.php:12` call `allowOrigin(true)`. In `objects/functions.php:2773-2790`, the `$allowAll=true` code path reflects any origin with credentials:This code path was **untouched** by commit `986e64aad`, which only hardened the default (`$allowAll=false`) path.Impact on data exposureBecause the victim's session cookies are sent with credentialed cross-origin requests, `User::isLogged()` returns true and `User::getId()` returns the victim's user ID. This means:**Video listing endpoint** (`get_api_video`): Sensitive user fields (email, isAdmin, etc.) are only stripped for unauthenticated requests (`functions.php:1752`), so authenticated CORS requests receive the full data.**User profile endpoint** (`get_api_user`): When `$isViewingOwnProfile` is true (line 3039), all sensitive fields including email, admin status, recovery tokens, and PII are returned unstripped.Additional issue: Referer header fallback`router.php` line 4 falls back to `HTTP_REFERER` when `HTTP_ORIGIN` is absent, injecting an attacker-controlled full URL (not just origin) into the `Access-Control-Allow-Origin` header. This is non-standard and could cause unexpected behavior.PoC**Step 1:** Host the following HTML on an attacker-controlled domain:**Step 2:** Victim visits attacker page while logged into AVideo.**Step 3:** The browser sends the request with victim's session cookies. `router.php` line 8 reflects the attacker's origin. `get.json.php` calls `allowOrigin(true)` which re-sets `Access-Control-Allow-Origin` to the attacker's origin with `Access-Control-Allow-Credentials: true`.**Step 4:** Browser permits cross-origin reading. Attacker receives the victim's full user profile including email, name, address, phone, admin status, and other PII.**For set endpoints (POST with custom headers requiring preflight):**The preflight OPTIONS is handled by `router.php` lines 14-18, which reflect the origin and exit — the CORS fix in `allowOrigin()` never runs.Impact**Data theft**: Any third-party website can read authenticated API responses for any logged-in AVideo user. This includes user profile data (email, real name, address, phone, admin status), video listings with creator PII, and other session-specific data.**Account information disclosure**: The user profile endpoint returns the full user record including `recoverPass` (password recovery token), `isAdmin` status, and all PII fields when accessed as the authenticated user.**Action on behalf of user**: Write endpoints (`set.json.php`) are equally affected, allowing cross-origin state-changing requests (creating playlists, modifying content, etc.) with the victim's session.**Bypass of intentional fix**: This directly circumvents the CORS hardening in commit `986e64aad`.Recommended Fix**1. Remove the independent CORS handler from `router.php`** and let `allowOrigin()` handle all CORS logic consistently:**2. Fix `allowOrigin($allowAll=true)` to validate origins** — or stop using it for API endpoints:Keep `allowOrigin(true)` only for genuinely public endpoints that return no session-sensitive data (VAST/VMAP ad XML).**3. As defense-in-depth**, set `SameSite=Lax` on session cookies to prevent browsers from sending them on cross-origin requests by default.
CVSS v3.1: 7.1