{"id":"7ef52d2e6594d7b8","repo":"gofiber/fiber","slug":"hostauthorization-forbidden-host","errorCode":null,"errorMessage":"hostauthorization: forbidden host","messagePattern":"hostauthorization: forbidden host","errorType":"http","errorClass":"ErrForbiddenHost","httpStatus":403,"severity":"warning","filePath":"middleware/hostauthorization/config.go","lineNumber":10,"sourceCode":"package hostauthorization\n\nimport (\n\t\"errors\"\n\n\t\"github.com/gofiber/fiber/v3\"\n)\n\n// ErrForbiddenHost is returned when the Host header does not match any allowed host.\nvar ErrForbiddenHost = errors.New(\"hostauthorization: forbidden host\")\n\n// Config defines the config for the host authorization middleware.\ntype Config struct {\n\t// Next defines a function to skip this middleware when returned true.\n\t// Use this to exclude health check endpoints or other paths from host validation.\n\t//\n\t// Optional. Default: nil\n\tNext func(c fiber.Ctx) bool\n\n\t// AllowedHostsFunc is a dynamic validator called only when no static\n\t// AllowedHosts rule matches. Receives the normalized hostname: port stripped,\n\t// trailing dot removed, IPv6 brackets removed, lowercased.\n\t// Return true to allow.\n\t//\n\t// Optional. Default: nil\n\tAllowedHostsFunc func(host string) bool\n\n\t// ErrorHandler is called when a request is rejected.","sourceCodeStart":1,"sourceCodeEnd":28,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/hostauthorization/config.go#L1-L28","documentation":"Returned by hostauthorization middleware (config.go:10) when the request's Host header, after normalization (port stripped, trailing dot removed, IPv6 brackets removed, lowercased, Punycode-converted), either fails to parse or does not match any entry in AllowedHosts (exact or wildcard) nor the AllowedHostsFunc fallback. The default ErrorHandler responds with 403 Forbidden (config.go:61-63). This is a Host header validation middleware that prevents host-header injection / virtual-host confusion attacks.","triggerScenarios":"Any request whose Host header is not in the allowlist: a direct-IP access when only domain names are allowed; a request to a staging domain on a production-configured app; a health-check from a load balancer using a raw IP; an attacker spoofing an arbitrary Host header. Also fires when parseNormalizedAuthority rejects malformed hosts (hostauthorization.go:292-294).","commonSituations":"Forgetting to list all domains the app is served under (apex + www, staging, internal); load balancer health checks using IP; accessing via localhost during development; adding a new domain alias without updating config; IDN domains not matching because of Punycode conversion differences.","solutions":["Add all legitimate hostnames to AllowedHosts including 'localhost' and IPs for development/health-checks.","Use AllowedHostsFunc for dynamic validation (e.g. database-backed host lists) when static rules are insufficient.","Set Config.Next to skip host validation for health-check endpoints.","For subdomains use the '*.example.com' wildcard form; list the apex separately since wildcards do not match the bare domain."],"exampleFix":"// before\napp.Use(hostauthorization.New(hostauthorization.Config{\n  AllowedHosts: []string{\"example.com\"},\n}))\n// after — cover apex, www, staging, and localhost\napp.Use(hostauthorization.New(hostauthorization.Config{\n  AllowedHosts: []string{\"example.com\", \"www.example.com\", \"*.staging.example.com\", \"localhost\", \"127.0.0.1\"},\n  Next: func(c fiber.Ctx) bool { return c.Path() == \"/health\" },\n}))","handlingStrategy":"validation","validationCode":"// Verify all expected hosts are allowed at startup\nallowed := map[string]bool{}\nfor _, h := range cfg.AllowedHosts { allowed[h] = true }\nfor _, expected := range []string{\"example.com\",\"www.example.com\",\"localhost\"} {\n    if !allowed[expected] { log.Printf(\"WARN: host %s not in AllowedHosts\", expected) }\n}","typeGuard":null,"tryCatchPattern":"// Custom error handler to log rejected hosts for diagnosis\ncfg.ErrorHandler = func(c fiber.Ctx, err error) error {\n    log.Printf(\"hostauthorization rejected host: %q\", c.Host())\n    return c.SendStatus(fiber.StatusForbidden)\n}","preventionTips":["List every domain the app is served under including localhost for dev.","Use Config.Next to skip health-check endpoints.","Remember wildcard '*.example.com' does not match the bare 'example.com'."],"tags":["hostauthorization","security","configuration","headers"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}