gchq/CyberChef · error · OperationError

Invalid Base64 payload

Error message

Invalid Base64 payload

What it means

Thrown by the Flask Session Decode operation when fromBase64() fails on the URL-safe base64 payload segment. After converting URL-safe characters (-/_ ) to standard base64 (+//) and padding, the payload should decode to a UTF-8 JSON string. If the payload is not valid base64, decoding throws.

Source

Thrown at src/core/operations/FlaskSessionDecode.mjs:64

        const payloadB64 = parts[0];
        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);

        const base64 = payloadB64.replace(/-/g, "+").replace(/_/g, "/");
        const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, "=");
        let payloadJson;
        try {
            payloadJson = fromBase64(padded);
        } catch (e) {
            throw new OperationError("Invalid Base64 payload");
        }

        try {
            let data = JSON.parse(payloadJson);

            if (args[0]) {
                data = {payload: data, timestamp: timestamp};
            }
            return data;
        } catch (e) {
            throw new OperationError("Unable to decode JSON payload: " + e.message);
        }
    }
}

export default FlaskSessionDecode;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Verify the first segment is valid URL-safe base64 (characters A-Z, a-z, 0-9, -, _).
  2. Re-capture the cookie to ensure it was not truncated during copy-paste.
  3. Confirm the input is actually a Flask session cookie and not another 3-segment token.
  4. Manually decode the payload segment in a base64url decoder to validate.

Example fix

// before: parts[0] = 'eyJ!!!invalid!!!' -> fromBase64 throws

// after: parts[0] = 'eyJ1c2VyIjoiYWRtaW4ifQ' (valid base64url JSON)
Defensive patterns

Strategy: validation

Validate before calling

// Validate payload segment is decodable base64url
const payload = input.trim().split('.')[0];
const b64 = payload.replace(/-/g, '+').replace(/_/g, '/');
const padded = b64.padEnd(Math.ceil(b64.length / 4) * 4, '=');
try { atob(padded); } catch { throw new Error('Invalid base64 payload'); }

Type guard

function isValidBase64UrlPayload(segment) {
  const b64 = segment.replace(/-/g, '+').replace(/_/g, '/');
  const padded = b64.padEnd(Math.ceil(b64.length / 4) * 4, '=');
  try { atob(padded); return true; } catch { return false; }
}

Prevention

When it happens

Trigger: run(input, args) at line 63 where fromBase64(padded) throws. The payload (parts[0]) after URL-safe-to-standard conversion and padding is not valid base64 data.

Common situations: The first segment of the cookie is corrupt, contains non-base64 characters, or is a truncated value. Also occurs if the input looked like a Flask cookie (3 parts) but is actually a different format.

Related errors


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