{"record":{"id":"5e9229d9eee4a113","repo":"phalcon/cphalcon","slug":"the-session-id-contains-invalid-characters","errorCode":null,"errorMessage":"The session id contains invalid characters","messagePattern":"The session id contains invalid characters","errorType":"exception","errorClass":"Phalcon\\Session\\Exceptions\\InvalidSessionId","httpStatus":null,"severity":"error","filePath":"phalcon/Session/Manager.zep","lineNumber":279,"sourceCode":"\n        return this;\n    }\n\n    /**\n     * Set session Id\n     *\n     * @return ManagerInterface\n     * @throws InvalidSessionId\n     * @throws SessionAlreadyStarted\n     */\n    public function setId(string sessionId) -> <ManagerInterface>\n    {\n        if unlikely (true === this->exists()) {\n            throw new SessionAlreadyStarted();\n        }\n\n        if unlikely !preg_match(\"/^[a-zA-Z0-9,-]+$/D\", sessionId) {\n            throw new InvalidSessionId();\n        }\n\n        session_id(sessionId);\n\n        return this;\n    }\n\n    /**\n     * Set the session name. Throw exception if the session has started\n     * and do not allow poop names\n     *\n     * @param string $name\n     *\n     * @return ManagerInterface\n     * @throws InvalidSessionName\n     * @throws SessionModificationDenied\n     */\n    public function setName(string name) -> <ManagerInterface>","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Session/Manager.zep#L261-L297","documentation":"Manager::setId() validates the id against /^[a-zA-Z0-9,-]+$/D, the PHP session id alphabet (letters, digits, comma, hyphen). InvalidSessionId is thrown for anything outside that set, including an empty string, +, /, =, _, dots and whitespace.","triggerScenarios":"Passing a base64 id (contains +/=), a base64url id (contains _), uniqid('', true) output (contains a dot), an empty string, or an id round-tripped from a cookie/query param of another app with a different alphabet; hex ids from bin2hex(random_bytes()) always pass.","commonSituations":"Hand-rolled id generation with base64_encode(random_bytes(...)) instead of bin2hex; SSO/multi-app setups where the sibling app issues ids with underscores; ids forwarded from URLs and passed to setId() unvalidated.","solutions":["Generate ids with bin2hex(random_bytes(16)) or session_create_id() — hex is always valid","Sanitize external ids: $id = preg_replace('/[^a-zA-Z0-9,-]/', '', $id); and fall back to a fresh id when the result is empty","For cross-application ids agree on the [a-zA-Z0-9,-] alphabet in the contract"],"exampleFix":"// before\n$session->setId(base64_encode(random_bytes(16))); // contains +/= -> InvalidSessionId\n\n// after\n$session->setId(bin2hex(random_bytes(16)));","handlingStrategy":"validation","validationCode":"function assertValidSessionId(string $id): string\n{\n    if (!preg_match('/^[a-zA-Z0-9,-]+$/D', $id)) {\n        throw new InvalidArgumentException('Session id violates [a-zA-Z0-9,-] alphabet');\n    }\n    return $id;\n}\n$session->setId(assertValidSessionId($incomingId));","typeGuard":"function isValidPhalconSessionId(string $id): bool\n{\n    return (bool) preg_match('/^[a-zA-Z0-9,-]+$/D', $id);\n}","tryCatchPattern":null,"preventionTips":["Generate ids with bin2hex(random_bytes(16)) or session_create_id(); never base64","Treat ids arriving from cookies, headers or query params as untrusted input","In SSO integrations, contract on the [a-zA-Z0-9,-] alphabet explicitly"],"tags":["php","phalcon","session","session-id","validation"],"backgroundTag":"invalid-session-id","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}