GitHub Security Advisory: GHSA-x3pr-vrhq-vq43
Package: wwbn/avideo (COMPOSER)
Severity: HIGH (CVSS 7.3)
CWE: CWE-384: Session Fixation
Vulnerable versions: <= 26.0
Patched in: unpatched

Summary: AVideo has Session Fixation via GET PHPSESSID Parameter With Disabled Login Session Regeneration

Details:
## Summary

AVideo's `_session_start()` function accepts arbitrary session IDs via the `PHPSESSID` GET parameter and sets them as the active PHP session. A session regeneration bypass exists for specific blacklisted endpoints when the request originates from the same domain. Combined with the explicitly disabled session regeneration in `User::login()`, this allows a classic session fixation attack where an attacker can fix a victim's session ID before authentication and then hijack the authenticated session.

## Details

The vulnerability is a chain of three weaknesses that together enable session fixation:

### 1. Attacker-controlled session ID acceptance (`objects/functionsPHP.php:344-367`)

```php
function _session_start(array $options = [])
{
    // ...
    if (isset($_GET['PHPSESSID']) && !_empty($_GET['PHPSESSID'])) {
        $PHPSESSID = $_GET['PHPSESSID'];
        // ...
        if (!User::isLogged()) {
            if ($PHPSESSID !== session_id()) {
                _session_write_close();
                session_id($PHPSESSID);   // <-- sets session to attacker's ID
            }
            $session = @session_start($options);  // <-- starts with attacker's ID
```

The code reads `$_GET['PHPSESSID']` and programmatically calls `session_id($PHPSESSID)`, which bypasses both `session.use_only_cookies` and `session.use_strict_mode` PHP settings since the session ID is set via the PHP API, not via cookie/URL handling.

### 2. Session regeneration bypass for blacklisted endpoints (`objects/functionsPHP.php:375-378`, `objects/functions.php:3100-3116`)

```php
// functionsPHP.php:375-378
if (!blackListRegenerateSession()) {
    _session_regenerate_id();  // <-- SKIPPED when blacklisted + same-domain
}
```

```php
// functions.php:3100-3116
function blackListRegenerateSession()
{
    if (!requestComesFromSafePlace()) {
        return false;
    }
    $list = [
        'objects/getCaptcha.php',
        'objects/userCreate.json.php',
        'objects/videoAddViewCount.json.php',
    ];
    foreach ($list as $needle) {
        if (str_ends_with($_SERVER['SCRIPT_NAME'], $needle)) {
            return true;  // <-- regeneration skipped for these endpoints
        }
    }
    return false;
}
```

The `requestComesFromSafePlace()` check at `objects/functionsSecurity.php:182` only verifies that `HTTP_REFERER` matches the AVideo domain. When a victim clicks a link from within the AVideo platform (e.g., in a comment or video description), the browser naturally sets the Referer to the AVideo domain, satisfying this check.

### 3. Disabled session regeneration on login (`objects/user.php:1315-1317`)

```php
// Call custom session regenerate logic
// this was regenerating the session all the time, making harder to save info in the session
//_session_regenerate_id();  // <-- COMMENTED OUT
```

The session regeneration after authentication is explicitly disabled. This means the session ID persists unchanged through the login transition, which is the fundamental