{"record":{"id":"9a5fb114a462ef29","repo":"gchq/CyberChef","slug":"invalid-flask-token-format-expected-payload-times","errorCode":null,"errorMessage":"Invalid Flask token format. Expected payload.timestamp.signature","messagePattern":"Invalid Flask token format\\. Expected payload\\.timestamp\\.signature","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/FlaskSessionDecode.mjs","lineNumber":43,"sourceCode":"        this.args = [\n            {\n                name: \"View TimeStamp\",\n                type: \"boolean\",\n                value: false\n            }\n        ];\n    }\n\n    /**\n     * @param {string} input\n     * @param {Object[]} args\n     * @returns {Object[]}\n     */\n    run(input, args) {\n        input = input.trim();\n        const parts = input.split(\".\");\n        if (parts.length !== 3) {\n            throw new OperationError(\"Invalid Flask token format. Expected payload.timestamp.signature\");\n        }\n\n        const payloadB64 = parts[0];\n        const time = parts[1];\n\n        const timeB64 = time.replace(/-/g, \"+\").replace(/_/g, \"/\");\n        const binary = fromBase64(timeB64);\n        const bytes = new Uint8Array(4);\n        for (let i = 0; i < 4; i++) {\n            bytes[i] = binary.charCodeAt(i);\n        }\n        const view = new DataView(bytes.buffer);\n        const timestamp = view.getInt32(0, false);\n\n        const base64 = payloadB64.replace(/-/g, \"+\").replace(/_/g, \"/\");\n        const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, \"=\");\n        let payloadJson;\n        try {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/FlaskSessionDecode.mjs#L25-L61","documentation":"Thrown by the Flask Session Decode operation when the input string does not split into exactly three dot-separated parts. Flask session cookies (itsdangerous) follow the format: base64url(payload).base64url(timestamp).base64url(signature). A different number of segments means the input is not a valid Flask session cookie.","triggerScenarios":"run(input, args) at line 42 where input.trim().split('.').length !== 3. This occurs when the input has fewer or more than two dots.","commonSituations":"Pasting a JWT (which has 3 segments but different structure), a Django session cookie, a random string, or a Flask cookie that has been truncated/corrupted. Also when extra whitespace or newlines affect splitting.","solutions":["Verify the input is a Flask session cookie with exactly two dots separating three base64url segments.","Capture the cookie from browser DevTools > Application > Cookies for a Flask-based site.","Remove any surrounding quotes, whitespace, or encoding artifacts.","If the cookie has a 'session=' prefix, strip it to just the token value."],"exampleFix":"// before: input = 'eyJ1c2VyIjoiYWRtaW4ifQ' (only 1 segment)\n\n// after: input = 'eyJ1c2VyIjoiYWRtaW4ifQ.Zmxhc2s=.abc123sig'\n//         (payload.timestamp.signature)","handlingStrategy":"validation","validationCode":"// Validate Flask cookie has 3 dot-separated segments\nconst parts = input.trim().split('.');\nif (parts.length !== 3) {\n  throw new Error('Input must be payload.timestamp.signature');\n}","typeGuard":"function isFlaskCookieFormat(str) {\n  const parts = str.trim().split('.');\n  return parts.length === 3 && parts.every(p => p.length > 0);\n}","tryCatchPattern":null,"preventionTips":["Confirm the input has exactly two dots.","Strip cookie name prefixes like 'session='.","Verify the source is a Flask application."],"tags":["crypto","flask","session","format-validation","cookie"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}