{"record":{"id":"da2dc62e864f8438","repo":"phpmyadmin/phpmyadmin","slug":"failed-to-generate-random-csrf-token","errorCode":null,"errorMessage":"Failed to generate random CSRF token!","messagePattern":"Failed to generate random CSRF token!","errorType":"exception","errorClass":"SessionHandlerException","httpStatus":null,"severity":"critical","filePath":"src/Session.php","lineNumber":57,"sourceCode":"     */\n    private static function generateToken(): void\n    {\n        /**\n         * Token which is used for authenticating access queries.\n         * (we use \"space PMA_token space\" to prevent overwriting)\n         */\n        $_SESSION[' PMA_token '] = Util::generateRandom(16, true);\n        $_SESSION[' HMAC_secret '] = Util::generateRandom(16);\n\n        /**\n         * Check if token is properly generated (the generation can fail, for example\n         * due to missing /dev/random for openssl).\n         */\n        if (self::getToken() !== '') {\n            return;\n        }\n\n        throw new SessionHandlerException('Failed to generate random CSRF token!');\n    }\n\n    public static function getToken(): string\n    {\n        if (isset($_SESSION[' PMA_token ']) && is_string($_SESSION[' PMA_token '])) {\n            return $_SESSION[' PMA_token '];\n        }\n\n        return '';\n    }\n\n    /**\n     * tries to secure session from hijacking and fixation\n     * should be called before login and after successful login\n     * (only required if sensitive information stored in session)\n     *\n     * @throws SessionHandlerException\n     */","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/phpmyadmin/phpmyadmin/blob/70d713dc39f5f7e0683c0ee38ab816b7e72b6a49/src/Session.php#L39-L75","documentation":"phpMyAdmin's session bootstrap needs a CSRF token in $_SESSION[' PMA_token ']. generateToken verifies the token after generation; if it is still empty (random_bytes/openssl_random_pseudo_bytes failed or the value never landed in the session), it throws SessionHandlerException.","triggerScenarios":"generateToken (from secure or setUp) runs, getToken() returns '' because no cryptographically secure RNG is available (missing /dev/random, disabled openssl extension, entropy exhaustion).","commonSituations":"Containers/chrooted environments lacking /dev/urandom; openssl or mbstring PHP extension missing; open_basedir blocking /dev/urandom; extremely low entropy systems.","solutions":["Ensure /dev/urandom (or /dev/random) exists and is readable by PHP","Enable the OpenSSL extension (or upgrade PHP >= 7 where random_bytes is built-in)","Check php.ini for open_basedir/disabled_functions blocking random sources","Fix session storage so $_SESSION writes persist, then retry"],"exampleFix":"// before (container without /dev/urandom)\nFatal: SessionHandlerException: Failed to generate random CSRF token!\n// after (Dockerfile)\nRUN mknod /dev/random c 1 8 && mknod /dev/urandom c 1 9 && chmod 666 /dev/random /dev/urandom\n; php.ini: extension=openssl","handlingStrategy":"validation","validationCode":"if (!is_readable('/dev/urandom') && !extension_loaded('openssl')) {\n    die('PHP needs a secure RNG: enable openssl or provide /dev/urandom');\n}\ntry { $probe = random_bytes(16); } catch (\\Random\\RandomException $e) { die('RNG unavailable'); }","typeGuard":null,"tryCatchPattern":"try {\n    Session::setUp($config, $request);\n} catch (SessionHandlerException $e) {\n    error_log('Session/RNG broken: ' . $e->getMessage());\n    http_response_code(500);\n    exit('Sessions are unavailable; fix PHP RNG/session configuration.');\n}","preventionTips":["Verify /dev/urandom exists in containers; create the device node if needed","Enable the OpenSSL PHP extension in all environments","Avoid open_basedir/disabled_functions rules blocking random sources","Smoke-test session + token generation in CI matching production image"],"tags":["session","csrf","php","security"],"backgroundTag":"missing-env-var","analyzedSha":"70d713dc39f5f7e0683c0ee38ab816b7e72b6a49","analyzedAt":"2026-09-13T19:13:03.620Z","contentChangedAt":"2026-09-13T19:13:03.620Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}