gchq/CyberChef · error · OperationError

Invalid Flask token format. Expected payload.timestamp.signa

Error message

Invalid Flask token format. Expected payload.timestamp.signature

What it means

Thrown by the Flask Session Verify operation when the input cookie string does not split into exactly three dot-separated parts. Flask session cookies use the itsdangerous format: payload.timestamp.signature. Verification requires all three segments to recompute and compare the HMAC.

Source

Thrown at src/core/operations/FlaskSessionVerify.mjs:73

     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {

        if (!args[0].string) {
            throw new OperationError("Secret key required");
        }

        const key = Utils.convertToByteString(args[0].string, args[0].option);
        const salt = Utils.convertToByteString(args[1].string || "cookie-session", args[1].option);
        const algorithm = args[2] || "sha1";

        input = input.trim();

        const parts = input.split(".");

        if (parts.length !== 3) {
            throw new OperationError("Invalid Flask token format. Expected payload.timestamp.signature");
        }

        const data = Utils.convertToByteString(parts[0] + "." + parts[1], "utf8");


        const derivedKey = CryptoApi.getHmac(key, CryptoApi.getHasher(algorithm));
        derivedKey.update(salt);

        const sign = CryptoApi.getHmac(derivedKey.finalize(), CryptoApi.getHasher(algorithm));
        sign.update(data);

        const payloadB64 = parts[0];
        const base64 = payloadB64.replace(/-/g, "+").replace(/_/g, "/");
        const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, "=");

        const time = parts[1];

        const timeB64 = time.replace(/-/g, "+").replace(/_/g, "/");

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Verify the input is a complete Flask session cookie with exactly three base64url segments separated by dots.
  2. Strip any 'session=' cookie-name prefix, leaving only the token value.
  3. Re-capture the cookie from browser DevTools to ensure completeness.
  4. Confirm the token is from Flask and not another framework.

Example fix

// before: input = 'session=eyJ1c2Vy...partial' (prefix + truncated)

// after: input = 'eyJ1c2VyIjoiYWRtaW4ifQ.Zmxhc2s=.abc123sig'
//         (clean payload.timestamp.signature)
Defensive patterns

Strategy: validation

Validate before calling

// Validate Flask cookie has 3 dot-separated segments before verifying
const parts = input.trim().split('.');
if (parts.length !== 3) {
  throw new Error('Input must be payload.timestamp.signature');
}

Type guard

function isFlaskCookieFormat(str) {
  const parts = str.trim().split('.');
  return parts.length === 3 && parts.every(p => p.length > 0);
}

Prevention

When it happens

Trigger: run(input, args) at line 72 where input.trim().split('.').length !== 3. The input has fewer or more than two dots after trimming.

Common situations: Pasting a non-Flask cookie, a truncated Flask cookie, or a JWT (which has 3 segments but a different signing scheme). Also when the 'session=' prefix is included or extra whitespace remains.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/2bc7d81f061377e0. Report an issue: GitHub.