{"record":{"id":"9da78911bf0271af","repo":"crowdsecurity/crowdsec","slug":"master-secret-is-d-bytes-minimum-is-d","errorCode":null,"errorMessage":"master secret is %d bytes; minimum is %d","messagePattern":"master secret is (.+?) bytes; minimum is (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/challenge/challenge.go","lineNumber":410,"sourceCode":"\t}\n\n\tlogger := resolvedOpts.logger\n\tif logger == nil {\n\t\tlogger = logging.SubLogger(log.StandardLogger(), \"challenge\", 0)\n\t}\n\n\tsecret := resolvedOpts.masterSecret\n\tif secret == nil {\n\t\tvar err error\n\t\tsecret, err = generateRandomSecret()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlogger.Warn(\"no master secret configured for the WAF challenge runtime; generated an ephemeral random secret. \" +\n\t\t\t\"Distributed (multi-WAF) deployments MUST configure a shared master_secret in the appsec config; \" +\n\t\t\t\"single-instance deployments will see outstanding challenge cookies invalidated on restart.\")\n\t} else if len(secret) < minSecretBytes {\n\t\treturn nil, fmt.Errorf(\"master secret is %d bytes; minimum is %d\", len(secret), minSecretBytes)\n\t}\n\n\trotationInterval := resolvedOpts.rotationInterval\n\tif rotationInterval == 0 {\n\t\trotationInterval = keyringDefaultRotation\n\t}\n\n\tkeys, err := NewKeyRing(secret, rotationInterval, resolvedOpts.maxLiveEpochs)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"build challenge keyring: %w\", err)\n\t}\n\tkeys.logger = logger\n\n\tcookieTTL := resolvedOpts.cookieTTL\n\tif cookieTTL <= 0 {\n\t\tcookieTTL = defaultCookieTTL\n\t}\n","sourceCodeStart":392,"sourceCodeEnd":428,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/challenge.go#L392-L428","documentation":"NewChallengeRuntime validates the configured master_secret length and rejects anything shorter than minSecretBytes. The challenge cookie keyring derives keys from this secret, so a too-short secret is insecure and startup is aborted. Note: an empty/absent secret is auto-generated with a warning, but a present-but-short secret is a hard error.","triggerScenarios":"Configuring the AppSec challenge runtime with a master_secret whose length is below minSecretBytes (e.g. 'secret', 'abc123').","commonSituations":"Hand-written appsec config with a short placeholder secret; operators shortening a secret to fit some other system; copy-pasted example config values.","solutions":["Set a master_secret of at least minSecretBytes bytes (32+ bytes recommended): openssl rand -base64 32.","In multi-WAF deployments, share the same sufficient-length secret across all AppSec instances.","Remove the master_secret field entirely to let the runtime generate an ephemeral one (single-instance only).","Store the secret via your config management/secrets manager rather than typing a short one manually."],"exampleFix":"// before (appsec config)\nmaster_secret: changeme\n// after\ngenerate with: openssl rand -base64 32\nmaster_secret: kJ8fQ2xN7vR4tYw9zLm3Bc6aHd1pSg5XeU0iFo8kZrTn=","handlingStrategy":"validation","validationCode":"// Go: validate secret length before writing config\nconst minSecretBytes = 32\nsecret, _ := base64.StdEncoding.DecodeString(cfg.MasterSecret)\nif len(secret) < minSecretBytes {\n    return fmt.Errorf(\"master_secret too short: %d bytes, need >= %d\", len(secret), minSecretBytes)\n}","typeGuard":null,"tryCatchPattern":"cr, err := NewChallengeRuntime(...)\nif err != nil {\n    if strings.Contains(err.Error(), \"master secret is\") {\n        return fmt.Errorf(\"appsec config: %w (generate with `openssl rand -base64 32`)\", err)\n    }\n    return err\n}","preventionTips":["Generate secrets with `openssl rand -base64 32` via your secrets manager","Add config linting that checks master_secret length in CI","Never use placeholder/example secrets in real deployments"],"tags":["go","security","configuration","secrets"],"backgroundTag":"invalid-config-value","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}