{"id":"2e507eed61a54cc6","repo":"gofiber/fiber","slug":"decode-sha256-password-w","errorCode":null,"errorMessage":"decode SHA256 password: %w","messagePattern":"decode SHA256 password: %w","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/basicauth/config.go","lineNumber":288,"sourceCode":"\tcase strings.HasPrefix(h, \"{SHA512}\"):\n\t\tb, err := base64.StdEncoding.DecodeString(h[len(\"{SHA512}\"):])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"decode SHA512 password: %w\", err)\n\t\t}\n\t\t// A digest of the wrong size can never equal a SHA-512 sum, so\n\t\t// accepting it would silently reject every password for this user.\n\t\t// Report it instead, which surfaces as a panic at startup.\n\t\tif len(b) != sha512.Size {\n\t\t\treturn nil, ErrInvalidSHA512PasswordLength\n\t\t}\n\t\treturn func(p string) bool {\n\t\t\tsum := sha512.Sum512([]byte(p))\n\t\t\treturn subtle.ConstantTimeCompare(sum[:], b) == 1\n\t\t}, nil\n\tcase strings.HasPrefix(h, \"{SHA256}\"):\n\t\tb, err := base64.StdEncoding.DecodeString(h[len(\"{SHA256}\"):])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"decode SHA256 password: %w\", err)\n\t\t}\n\t\tif len(b) != sha256.Size {\n\t\t\treturn nil, ErrInvalidSHA256PasswordLength\n\t\t}\n\t\treturn func(p string) bool {\n\t\t\tsum := sha256.Sum256([]byte(p))\n\t\t\treturn subtle.ConstantTimeCompare(sum[:], b) == 1\n\t\t}, nil\n\tdefault:\n\t\tb, err := hex.DecodeString(h)\n\t\tif err != nil || len(b) != sha256.Size {\n\t\t\tif b, err = base64.StdEncoding.DecodeString(h); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"decode SHA256 password: %w\", err)\n\t\t\t}\n\t\t\tif len(b) != sha256.Size {\n\t\t\t\treturn nil, ErrInvalidSHA256PasswordLength\n\t\t\t}\n\t\t}","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/basicauth/config.go#L270-L306","documentation":"Returned by parseHashedPassword when a Users value starts with '{SHA256}' but the trailing bytes are not decodable as standard base64. Equivalent to the SHA512 case but expects a 32-byte SHA-256 digest encoded with standard base64 (the Apache '{SHA}' htpasssd style but for SHA-256). Causes startup setup() to fail.","triggerScenarios":"Users map entry like \"{SHA256}\" + a hex string, a URL-safe base64 string, a value with truncated padding, or stray whitespace. Also triggered by feeding a digest generated by a tool that defaults to hex (sha256sum) without re-encoding to base64.","commonSituations":"Running 'echo -n pass | sha256sum' (hex) and pasting after '{SHA256}'; copy/paste dropping '=' padding; YAML/JSON parser stripping trailing '='; using base64 -w0 with URL-safe mode (-e vs -u confusion).","solutions":["Produce the expected encoding: printf '%s' \"$PW\" | openssl dgst -sha256 -binary | base64, prefix with '{SHA256}'.","Remove any embedded whitespace/newlines from the digest before storing.","Use standard base64 (A–Z, a–z, 0–9, +, /, '=' padding); avoid URL-safe or hex.","Verify decoded length is 32 bytes to avoid the follow-on ErrInvalidSHA256PasswordLength."],"exampleFix":"// before: 'sha256sum' hex output after the prefix\nusers := map[string]string{\"bob\": \"{SHA256}\" + hexDigest}\n\n// after: raw SHA-256 bytes in standard base64\n// $ printf '%s' 'hunter2' | openssl dgst -sha256 -binary | base64\nusers := map[string]string{\"bob\": \"{SHA256}\" + b64Digest}","handlingStrategy":"validation","validationCode":"func validSHA256Entry(v string) error {\n    const p = \"{SHA256}\"\n    if !strings.HasPrefix(v, p) {\n        return fmt.Errorf(\"missing %q prefix\", p)\n    }\n    b, err := base64.StdEncoding.DecodeString(v[len(p):])\n    if err != nil {\n        return fmt.Errorf(\"not standard base64: %w\", err)\n    }\n    if len(b) != sha256.Size {\n        return fmt.Errorf(\"decoded length %d != %d\", len(b), sha256.Size)\n    }\n    return nil\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Generate digests with: printf '%s' \"$PW\" | openssl dgst -sha256 -binary | base64.","Don't feed 'sha256sum' hex output to {SHA256}.","Preserve trailing '=' padding when copying values.","Use standard base64 (+, /), not URL-safe (-, _) or hex."],"tags":["basicauth","authentication","passwords","sha256","base64","config"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}