{"id":"373f1aada4c9e135","repo":"gofiber/fiber","slug":"decode-sha512-password-w","errorCode":null,"errorMessage":"decode SHA512 password: %w","messagePattern":"decode SHA512 password: %w","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/basicauth/config.go","lineNumber":273,"sourceCode":"func (s verifierStrength) betterThan(other verifierStrength) bool {\n\tif s.algorithm != other.algorithm {\n\t\treturn s.algorithm > other.algorithm\n\t}\n\n\treturn s.cost > other.cost\n}\n\nfunc parseHashedPassword(h string) (passwordVerifier, error) {\n\tswitch {\n\tcase strings.HasPrefix(h, \"$2\"):\n\t\thash := []byte(h)\n\t\treturn func(p string) bool {\n\t\t\treturn bcrypt.CompareHashAndPassword(hash, []byte(p)) == nil\n\t\t}, nil\n\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","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/basicauth/config.go#L255-L291","documentation":"Emitted by parseHashedPassword when a Users entry begins with the literal '{SHA512}' prefix but the remainder is not valid standard base64. Fiber expects '{SHA512}' immediately followed by the base64-encoded 64-byte SHA-512 digest of the password (binary form, not hex). This is the Apache htpasswd '{SHA}'-style scheme; any base64 corruption — wrong padding, URL-safe alphabet, or truncation — surfaces here.","triggerScenarios":"Configuring middleware/basicauth with Users map[string]string where a value is \"{SHA512}\" + something that base64.StdEncoding.DecodeString rejects: e.g. '{SHA512}dGhpcyBpc', missing '==' padding, contains '-'/'_' (URL-safe alphabet), or has whitespace/newline. A digest produced with 'openssl dgst -sha512 | cut' (hex output) instead of raw bytes also fails.","commonSituations":"Generating the hash with the wrong tool (printf of hex instead of base64); copying the value from a YAML that ate trailing '=' padding; mixing up {SHA256} vs {SHA512} digests; pasting a value that wrapped across lines in the terminal.","solutions":["Regenerate the digest as raw bytes in standard base64: printf '%s' \"$PW\" | openssl dgst -sha512 -binary | base64, then set Users[u] = \"{SHA512}\" + that.","Strip any whitespace/newlines from the value before embedding it in config.","Make sure the value uses standard base64 (+ and /, = padding), not URL-safe (- and _) or hex.","Confirm length is 64 bytes after decode, or you'll next hit ErrInvalidSHA512PasswordLength."],"exampleFix":"// before: hex digest after the prefix -> base64 decode fails\nusers := map[string]string{\"alice\": \"{SHA512}\" + hexSHA512}\n\n// after: raw bytes, standard base64\n// $ printf '%s' 'hunter2' | openssl dgst -sha512 -binary | base64\nusers := map[string]string{\"alice\": \"{SHA512}\" + b64RawBytes}","handlingStrategy":"validation","validationCode":"// Validate a {SHA512} password entry before configuring basicauth.\nfunc validSHA512Entry(v string) error {\n    const p = \"{SHA512}\"\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) != sha512.Size {\n        return fmt.Errorf(\"decoded length %d != %d\", len(b), sha512.Size)\n    }\n    return nil\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Generate digests with: printf '%s' \"$PW\" | openssl dgst -sha512 -binary | base64.","Never paste hex output after the {SHA512} prefix.","Strip whitespace/newlines from the encoded value in config files.","Add a unit test that runs parseHashedPassword over every entry at startup."],"tags":["basicauth","authentication","passwords","sha512","base64","config"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}