{
    "slug": "php_sessions",
    "term": "PHP Sessions",
    "category": "php",
    "difficulty": "beginner",
    "short": "Server-side state storage identified by a cookie-based session ID — PHP's built-in mechanism for persisting data across HTTP requests, with security implications for how the session is started, stored, and terminated.",
    "long": "PHP sessions work by: session_start() checks for a session cookie (PHPSESSID by default), creates a new session file (or entry in Redis/database) if none exists, and populates the $_SESSION superglobal from stored data. Session data is serialised to disk by default (session.save_path) or to a custom handler (Redis, Memcached, database). The session ID is sent to the browser as a cookie. Security requirements: session.cookie_httponly = true (prevents JavaScript access); session.cookie_secure = true (HTTPS only); session.cookie_samesite = 'Lax' (CSRF protection); session.use_strict_mode = true (rejects unrecognised session IDs); session_regenerate_id(true) after login (destroys old session, creates new — prevents session fixation); session_destroy() on logout (invalidates server-side data). PHP file-based sessions do not scale across multiple servers — use Redis or a database session handler for multi-server deployments.",
    "aliases": [
        "$_SESSION",
        "session_start",
        "PHPSESSID",
        "session handling",
        "PHP session"
    ],
    "tags": [
        "sessions",
        "php",
        "security",
        "authentication",
        "cookies",
        "state"
    ],
    "misconception": "Sessions are automatically secure when used with HTTPS. HTTPS encrypts the session ID in transit but does not prevent session fixation (where an attacker sets the session ID before login), session hijacking (where a valid session ID is stolen from an XSS vulnerability or network interception), or session persistence after logout (where session data remains on the server). All four security controls — httponly cookie, secure cookie, SameSite, and session_regenerate_id — are required together.",
    "why_it_matters": "Sessions are the default state mechanism for PHP web applications and the most common place authentication bugs are introduced. Missing session.cookie_httponly allows XSS to steal the session ID. Missing session_regenerate_id(true) after login allows session fixation. Using file-based sessions on a load-balanced server cluster causes users to be logged out when requests route to different servers. These are not theoretical issues — they are the actual vulnerabilities exploited in PHP application attacks.",
    "common_mistakes": [
        "Not calling session_start() at the beginning of every page that uses sessions — $_SESSION is empty without it.",
        "Not regenerating the session ID after login — exposes the application to session fixation attacks.",
        "Using file-based sessions in a multi-server environment — sessions are not shared across servers; use Redis.",
        "Not calling session_destroy() on logout — invalidating the cookie without destroying the server-side data leaves the session exploitable if the cookie is obtained."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "authentication",
        "session_fixation",
        "csrf",
        "insecure_cookie"
    ],
    "prerequisites": [],
    "refs": [
        "https://www.php.net/manual/en/book.session.php"
    ],
    "bad_code": "<?php\nsession_start();\n// Login check — no regeneration\nif (checkCredentials($_POST['user'], $_POST['pass'])) {\n    $_SESSION['user'] = $_POST['user'];\n    // No session_regenerate_id — session fixation possible\n    // No secure/httponly cookie settings\n}",
    "good_code": "<?php\n// Secure session configuration\nini_set('session.cookie_httponly', '1');\nini_set('session.cookie_secure', '1');\nini_set('session.cookie_samesite', 'Lax');\nini_set('session.use_strict_mode', '1');\n\nsession_start();\n\nif (checkCredentials($_POST['user'], $_POST['pass'])) {\n    session_regenerate_id(true); // new ID, old destroyed\n    $_SESSION['user_id']    = getUserId($_POST['user']);\n    $_SESSION['logged_in']  = true;\n    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));\n    header('Location: /dashboard');\n    exit;\n}",
    "quick_fix": "Set cookie_httponly, cookie_secure, cookie_samesite=Lax in php.ini or session_set_cookie_params(), call session_regenerate_id(true) after login, session_destroy() on logout",
    "severity": "high",
    "effort": "low",
    "created": "2026-03-23",
    "updated": "2026-04-04",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/php_sessions",
        "html_url": "https://codeclaritylab.com/glossary/php_sessions",
        "json_url": "https://codeclaritylab.com/glossary/php_sessions.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[PHP Sessions](https://codeclaritylab.com/glossary/php_sessions) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/php_sessions"
            }
        }
    }
}