{"record":{"id":"e38a9a2c517a1c34","repo":"crowdsecurity/crowdsec","slug":"errcookietoolarge","errorCode":"ErrCookieTooLarge","errorMessage":"%w: plaintext=%d > %d","messagePattern":"%w: plaintext=(.+?) > (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/challenge/crypto.go","lineNumber":135,"sourceCode":"\tkey, err := deriveKey(masterCookieKey)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tblock, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create cipher: %w\", err)\n\t}\n\n\tgcm, err := cipher.NewGCM(block)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create GCM: %w\", err)\n\t}\n\n\t// Reject an over-limit envelope before marshaling it.\n\tmaxPlaintext := maxCookieLen/4*3 - 1 - gcm.NonceSize() - gcm.Overhead()\n\tif plaintextLen := cookiePlaintextFixedHeaderLen + len(reason) + proto.Size(envelope); plaintextLen > maxPlaintext {\n\t\treturn \"\", fmt.Errorf(\"%w: plaintext=%d > %d\", ErrCookieTooLarge, plaintextLen, maxPlaintext)\n\t}\n\n\tenvelopeBytes, err := proto.Marshal(envelope)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to marshal challenge cookie proto: %w\", err)\n\t}\n\n\tnonce := make([]byte, gcm.NonceSize())\n\tif _, err := rand.Read(nonce); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to generate nonce: %w\", err)\n\t}\n\n\t// Build the plaintext: not_after_be8 || flags || reason_len_be || reason || envelope\n\tplaintext := make([]byte, 0, cookiePlaintextFixedHeaderLen+len(reason)+len(envelopeBytes))\n\n\tvar notAfterBytes [8]byte\n\tbinary.BigEndian.PutUint64(notAfterBytes[:], uint64(notAfter))\n\tplaintext = append(plaintext, notAfterBytes[:]...)","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/crypto.go#L117-L153","documentation":"Before marshaling, sealCookieV0 pre-computes the plaintext size (fixed 11-byte header + reason + protobuf envelope) and rejects anything exceeding the space available within maxCookieLen after base64 expansion, GCM nonce (12 bytes) and tag (16 bytes). The sentinel error is ErrCookieTooLarge. This guards against the 4 KB browser cookie limit and bounds attacker-influenced envelope allocation.","triggerScenarios":"Calling sealCookieV0 with an envelope whose protobuf size plus reason length exceeds maxPlaintext = maxCookieLen/4*3 - 1 - 12 - 16; with default maxCookieLen 4096 that is ~3040 bytes. Reached via SealAllowlistCookie (large reason) or ValidateChallengeResponse (large fingerprint proto), or when max_cookie_size is configured lower than the payload.","commonSituations":"Deployments lowering max_cookie_size in appsec config below what the fingerprint envelope requires; unusually large fingerprint data (many attributes) stored in the envelope; an allowlist reason near the 256-byte cap combined with a big proto.","solutions":["Raise the max_cookie_size challenge config value (default 4096) if the client tolerates larger cookies.","Reduce the reason length (allowlist cookies) or slim the fingerprint envelope payload.","Match errors.Is(err, challenge.ErrCookieTooLarge) to surface a clear 'cookie too large' message instead of a generic seal failure."],"exampleFix":"# before\nmax_cookie_size: 2048\n# after\nmax_cookie_size: 4096","handlingStrategy":"validation","validationCode":"const maxCookieSize = 4096 // must be >= default; keep headroom for reason + envelope\nif cfg.MaxCookieSize != nil && *cfg.MaxCookieSize < 4096 {\n    log.Warn(\"max_cookie_size below default may reject valid fingerprint envelopes\")\n}","typeGuard":null,"tryCatchPattern":"if err := errors.Is(err, challenge.ErrCookieTooLarge); err != nil {\n    // raise max_cookie_size or trim reason/envelope, then retry once\n}","preventionTips":["Leave max_cookie_size at the 4096 default unless the client cannot carry 4 KB cookies.","Keep the fingerprint envelope small; do not stuff extra data into it.","Budget: reason (max 256) + envelope must fit in ~3040 plaintext bytes."],"tags":["appsec","cookie","size-limit","validation"],"backgroundTag":"payload-too-large","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}