{"id":"GHSA-x3pr-vrhq-vq43","summary":"AVideo has Session Fixation via GET PHPSESSID Parameter With Disabled Login Session Regeneration","details":"## Summary\n\nAVideo'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.\n\n## Details\n\nThe vulnerability is a chain of three weaknesses that together enable session fixation:\n\n### 1. Attacker-controlled session ID acceptance (`objects/functionsPHP.php:344-367`)\n\n```php\nfunction _session_start(array $options = [])\n{\n    // ...\n    if (isset($_GET['PHPSESSID']) && !_empty($_GET['PHPSESSID'])) {\n        $PHPSESSID = $_GET['PHPSESSID'];\n        // ...\n        if (!User::isLogged()) {\n            if ($PHPSESSID !== session_id()) {\n                _session_write_close();\n                session_id($PHPSESSID);   // \u003c-- sets session to attacker's ID\n            }\n            $session = @session_start($options);  // \u003c-- starts with attacker's ID\n```\n\nThe 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.\n\n### 2. Session regeneration bypass for blacklisted endpoints (`objects/functionsPHP.php:375-378`, `objects/functions.php:3100-3116`)\n\n```php\n// functionsPHP.php:375-378\nif (!blackListRegenerateSession()) {\n    _session_regenerate_id();  // \u003c-- SKIPPED when blacklisted + same-domain\n}\n```\n\n```php\n// functions.php:3100-3116\nfunction blackListRegenerateSession()\n{\n    if (!requestComesFromSafePlace()) {\n        return false;\n    }\n    $list = [\n        'objects/getCaptcha.php',\n        'objects/userCreate.json.php',\n        'objects/videoAddViewCount.json.php',\n    ];\n    foreach ($list as $needle) {\n        if (str_ends_with($_SERVER['SCRIPT_NAME'], $needle)) {\n            return true;  // \u003c-- regeneration skipped for these endpoints\n        }\n    }\n    return false;\n}\n```\n\nThe `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.\n\n### 3. Disabled session regeneration on login (`objects/user.php:1315-1317`)\n\n```php\n// Call custom session regenerate logic\n// this was regenerating the session all the time, making harder to save info in the session\n//_session_regenerate_id();  // \u003c-- COMMENTED OUT\n```\n\nThe session regeneration after authentication is explicitly disabled. This means the session ID persists unchanged through the login transition, which is the fundamental requirement for session fixation to succeed.\n\n### Amplifying factors\n\n- `objects/phpsessionid.json.php` exposes session IDs to any same-origin JavaScript without authentication (line 12: `$obj-\u003ephpsessid = session_id()`)\n- `view/js/session.js` stores the session ID in a global `window.PHPSESSID` variable and logs it to console (line 15)\n- No session-to-IP or session-to-user-agent binding exists (verified via codebase search)\n\n## PoC\n\n### Step 1: Attacker obtains a session ID\n\n```bash\n# Attacker visits the site to get a valid session ID\ncurl -v https://target.example.com/ 2\u003e&1 | grep 'set-cookie.*PHPSESSID'\n# Response: Set-Cookie: PHPSESSID=attacker_known_session_id; ...\n```\n\n### Step 2: Attacker injects a link on the platform\n\nThe attacker posts a comment on a video or creates content containing a link:\n\n```\nhttps://target.example.com/objects/getCaptcha.php?PHPSESSID=attacker_known_session_id\n```\n\nThis can be placed in a video comment, video description, user bio, or forum post — anywhere AVideo renders user-provided links.\n\n### Step 3: Victim clicks the link while browsing AVideo\n\nWhen the victim clicks the link from within the AVideo platform:\n1. Browser sets `Referer: https://target.example.com/...` (same-domain)\n2. `_session_start()` processes `$_GET['PHPSESSID']`, victim is not logged in, so `session_id('attacker_known_session_id')` is called\n3. `blackListRegenerateSession()` returns `true` (script is `getCaptcha.php` + same-domain Referer)\n4. `_session_regenerate_id()` is **skipped**\n5. Victim's session is now fixed to `attacker_known_session_id`\n\n### Step 4: Victim logs in\n\nThe victim navigates to the login page and authenticates. `User::login()` populates `$_SESSION['user']` but does NOT regenerate the session ID (line 1317 is commented out).\n\n### Step 5: Attacker hijacks the authenticated session\n\n```bash\n# Attacker uses the known session ID to access victim's account\ncurl -b \"PHPSESSID=attacker_known_session_id\" https://target.example.com/objects/user.php?userAPI=1\n# Response: victim's user data, confirming session hijack\n```\n\n## Impact\n\n- **Full account takeover**: An attacker can hijack any user's authenticated session, including administrator accounts\n- **Data access**: Full access to the victim's videos, private content, messages, and personal information\n- **Privilege escalation**: If the victim is an admin, the attacker gains full administrative control over the AVideo instance\n- **Lateral actions**: The attacker can perform any action as the victim — upload/delete content, modify settings, access admin panel\n\n## Recommended Fix\n\n### Fix 1: Re-enable session regeneration on login (`objects/user.php:1317`)\n\n```php\n// Replace the commented-out line:\n//_session_regenerate_id();\n\n// With:\n_session_regenerate_id();\n```\n\nThis is the most critical fix. Session regeneration on authentication transition is a fundamental defense against session fixation (OWASP recommendation).\n\n### Fix 2: Remove GET-based session ID acceptance (`objects/functionsPHP.php:344-383`)\n\nRemove or restrict the `$_GET['PHPSESSID']` handling entirely. If it is needed for specific use cases (e.g., CAPTCHA), validate the session ID against a server-side token rather than blindly accepting arbitrary values:\n\n```php\n// Instead of accepting any GET PHPSESSID, remove this block entirely.\n// If CAPTCHA requires session continuity, pass a CSRF token instead.\nif (isset($_GET['PHPSESSID']) && !_empty($_GET['PHPSESSID'])) {\n    // REMOVED: Do not accept session IDs from URL parameters\n}\n```\n\n### Fix 3: Remove session ID exposure (`objects/phpsessionid.json.php`, `view/js/session.js`)\n\nThe `phpsessionid.json.php` endpoint and the `session.js` global variable negate the `httponly` cookie flag. If JavaScript needs to reference the session for AJAX requests, the browser automatically includes session cookies — there is no need to expose the session ID value to JavaScript.","aliases":["CVE-2026-33492"],"modified":"2026-03-25T20:48:38.031417Z","published":"2026-03-20T20:49:23Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2026-03-20T20:49:23Z","nvd_published_at":"2026-03-23T16:16:49Z","cwe_ids":["CWE-384"],"severity":"HIGH"},"references":[{"type":"WEB","url":"https://github.com/WWBN/AVideo/security/advisories/GHSA-x3pr-vrhq-vq43"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33492"},{"type":"WEB","url":"https://github.com/WWBN/AVideo/commit/5647a94d79bf69a972a86653fe02144079948785"},{"type":"PACKAGE","url":"https://github.com/WWBN/AVideo"}],"affected":[{"package":{"name":"wwbn/avideo","ecosystem":"Packagist","purl":"pkg:composer/wwbn/avideo"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"26.0"}]}],"versions":["10.4","10.8","11","11.1","11.1.1","11.5","11.6","12.4","14.3","14.3.1","14.4","18.0","21.0","22.0","24.0","25.0","26.0"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-x3pr-vrhq-vq43/GHSA-x3pr-vrhq-vq43.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N"}]}