GitHub Security Advisory: GHSA-g8x9-7mgh-7cvj
Package: wwbn/avideo (COMPOSER)
Severity: HIGH (CVSS 8.1)
CWE: CWE-352: Cross-Site Request Forgery (CSRF)
Vulnerable versions: <= 26.0
Patched in: unpatched

Summary: AVideo's GET-Based CSRF in setPermission.json.php Enables Privilege Escalation via Arbitrary Permission Modification

Details:
## Summary

The `plugin/Permissions/setPermission.json.php` endpoint accepts GET parameters for a state-changing operation that modifies user group permissions. The endpoint has no CSRF token validation, and the application explicitly sets `session.cookie_samesite=None` on session cookies. This allows an unauthenticated attacker to craft a page with `<img>` tags that, when visited by an admin, silently grant arbitrary permissions to the attacker's user group — escalating the attacker to near-admin access.

## Details

The root cause is a combination of three issues:

**1. `$_REQUEST` used instead of `$_POST` (accepts GET parameters):**

`plugin/Permissions/setPermission.json.php:14-24`:
```php
$intvalList = array('users_groups_id','plugins_id','type','isEnabled');
foreach ($intvalList as $value) {
    if($_REQUEST[$value]==='true'){
        $_REQUEST[$value] = 1;
    }else{
        $_REQUEST[$value] = intval($_REQUEST[$value]);
    }
}

$obj = new stdClass();
$obj->id = Permissions::setPermission($_REQUEST['users_groups_id'], $_REQUEST['plugins_id'], $_REQUEST['type'], $_REQUEST['isEnabled']);
```

The only authorization check is `User::isAdmin()` at line 10 — there is no CSRF token validation via `isGlobalTokenValid()`.

**2. Session cookies set to `SameSite=None`:**

`objects/include_config.php:134-141`:
```php
if ($isHTTPS) {
    // SameSite=None is intentional: AVideo supports cross-origin iframe embedding
    ini_set('session.cookie_samesite', 'None');
    ini_set('session.cookie_secure', '1');
}
```

This means the admin's session cookie is sent on cross-origin requests, including those initiated by `<img src="...">` tags on attacker-controlled pages.

**3. The codebase's own security model requires CSRF tokens on state-mutating endpoints:**

The comment at `include_config.php:137-138` states: *"All state-mutating endpoints that are vulnerable to CSRF must instead enforce a short-lived globalToken (verifyToken)."* Other endpoints like `saveSort.json.php` and `pluginImport.json.php` enforce `isGlobalTokenValid()`, but `setPermission.json.php` does not.

**Execution flow:**
1. Attacker hosts a page containing `<img src="https://target/plugin/Permissions/setPermission.json.php?users_groups_id=2&plugins_id=1&type=10&isEnabled=true">`
2. Admin visits the page (e.g., via link in forum, email, or embedded content)
3. Browser issues GET request with the admin's `SameSite=None` session cookie
4. `User::isAdmin()` passes because the request carries the admin's session
5. `Permissions::setPermission()` grants PERMISSION_FULLACCESSVIDEOS (type=10) to user group 2
6. Any user in group 2 (including the attacker) now has full video admin access

The `users_groups_id` values are small sequential integers (typically 1-3 for default groups) and can be trivially enumerated.

## PoC

**Step 1: Attacker creates a page granting multiple permissions to their user group (ID 2):**

```html
<!DOCTYPE html>
<html>
<head><title>Interesting Video</title></head>
<body>