gchq/CyberChef · error · OperationError

Invalid Base64 payload

Error message

Invalid Base64 payload

What it means

Thrown by the Flask Session Verify operation when the payload segment (parts[0]) of the cookie cannot be decoded as Base64. The code first converts URL-safe characters (-/_ ) to standard (+//) and pads with '=', then calls fromBase64(padded); any failure is caught and rethrown as this OperationError. It signals that the first dotted segment is not a valid Base64-encoded payload, so the cookie structure is wrong before signature checking even begins.

Source

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

        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, "/");
        const binary = fromBase64(timeB64);
        const bytes = new Uint8Array(4);
        for (let i = 0; i < 4; i++) {
            bytes[i] = binary.charCodeAt(i);
        }
        const view = new DataView(bytes.buffer);
        const timestamp = view.getInt32(0, false);

        let payloadJson;
        try {
            payloadJson = fromBase64(padded);
        } catch (e) {
            throw new OperationError("Invalid Base64 payload");
        }

        const signB64 = toBase64(sign.finalize());
        const sign64 = signB64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");

        if (sign64 !== parts[2]) {
            throw new OperationError("Invalid signature!");
        }

        try {
            const decoded = JSON.parse(payloadJson);
            if (!args[3]) {
                return {
                    valid: true,
                    payload: decoded,
                };
            } else {
                return {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Confirm the input is a real Flask session cookie of the form payload.timestamp.signature produced by itsdangerous/Flask.
  2. Verify segment 0 (before the first dot) only contains URL-safe Base64 chars [A-Za-z0-9_-] and is complete.
  3. Ensure the input is pasted verbatim without trimming internal characters; only leading/trailing whitespace is stripped by the operation.
  4. If testing manually, generate a known-good cookie via Flask and feed that in to isolate the problem.

Example fix

// before: feeding a non-Flask token
verify.run('eyJhbGci.foo.bar', args) // wrong shape
// after: feed a genuine Flask session cookie
verify.run('eyJ1c2VyIjoiYWxpY2UifQ.ZmFrZS5zaWc', args)
Defensive patterns

Strategy: validation

Validate before calling

// Validate a Flask session cookie payload segment is URL-safe Base64 before calling run()
function isValidPayloadB64(seg) {
  const std = seg.replace(/-/g, '+').replace(/_/g, '/');
  return /^[A-Za-z0-9+/]*={0,2}$/.test(std.padEnd(Math.ceil(std.length / 4) * 4, '='));
}
const parts = cookie.trim().split('.');
if (parts.length !== 3 || !isValidPayloadB64(parts[0])) {
  // do not call run(); handle gracefully
}

Type guard

// Narrow a string to a plausibly-shaped Flask session cookie
function isFlaskCookieShape(s) {
  const parts = String(s).trim().split('.');
  return parts.length === 3 && parts.every(p => /^[A-Za-z0-9_-]+$/.test(p));
}

Try / catch

try {
  const result = flaskVerify.run(cookie, args);
} catch (e) {
  if (e.type === 'OperationError' && /Invalid Base64 payload/.test(e.message)) {
    // cookie payload is malformed; surface a friendly message
  } else throw e;
}

Prevention

When it happens

Trigger: Running Flask Session Verify on a string whose first dot-delimited segment is not Base64 (e.g. an edited/truncated payload, a non-Flask cookie, or a cookie where the payload contains characters outside the URL-safe Base64 alphabet after conversion). Also triggered if parts.length is 3 by accident but segment 0 is arbitrary text.

Common situations: Pasting a JWT or other signed token that is not an itsdangerous Flask session cookie; copying only part of the cookie; URL-decoding artifacts left in the payload; mismatched delimiters causing the split to misalign segments.

Related errors


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