You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Useful for services accessed directly by IP (e.g. internal tooling) where the `Host` header will be a raw IP address. This matches the **Host header value** against a CIDR range — it does not filter by client IP address:
65
+
Browsers always transmit the `Host` header in ASCII (Punycode) form, so IDN entries in `AllowedHosts` are converted to Punycode at startup. You can configure entries in either form — they are equivalent:
The default response is **403 Forbidden**. **421 Misdirected Request** ([RFC 9110 §15.5.20](https://www.rfc-editor.org/rfc/rfc9110#section-15.5.20)) is a semantically closer choice for "wrong host for this server" — CDNs like Cloudflare and Fastly use it for this case. Either is reasonable; pick one via `ErrorHandler`:
| Next |`func(fiber.Ctx) bool`| Defines a function to skip this middleware when returned true. |`nil`|
158
-
| AllowedHosts |`[]string`| List of permitted hosts. Supports exact match, subdomain wildcard (`.example.com`), and CIDR.|`nil`|
159
-
| AllowedHostsFunc |`func(string) bool`| Dynamic validator called only when no static AllowedHosts rule matches. Receives the normalized hostname: port stripped, trailing dot removed, IPv6 brackets removed, lowercased. |`nil`|
162
+
| AllowedHosts |`[]string`| List of permitted hosts. Supports exact match and subdomain wildcard (`*.example.com`). |`nil`|
163
+
| AllowedHostsFunc |`func(string) bool`| Dynamic validator called only when no static AllowedHosts rule matches. Receives the normalized hostname: port stripped, trailing dot removed, IPv6 brackets removed, lowercased, IDN converted to Punycode. |`nil`|
160
164
| ErrorHandler |`fiber.ErrorHandler`| Called when a request is rejected. Receives `ErrForbiddenHost` as the error. | 403 |
161
165
162
166
Either `AllowedHosts` or `AllowedHostsFunc` (or both) must be provided. The middleware panics at startup if neither is set.
@@ -173,23 +177,26 @@ There is no useful default — you must provide at least `AllowedHosts` or `Allo
173
177
174
178
The middleware matches hosts in this order:
175
179
176
-
1.**Exact match** — case-insensitive, port and trailing dot stripped
177
-
2.**Subdomain wildcard** — `".myapp.com"` matches `api.myapp.com` but not `myapp.com`
178
-
3.**CIDR range** — host is parsed as IP and checked against the network
179
-
4.**AllowedHostsFunc** — called only if no static rule matched
180
+
1.**Exact match** — case-insensitive, port and trailing dot stripped, IDN labels in Punycode form
181
+
2.**Subdomain wildcard** — `"*.myapp.com"` matches `api.myapp.com` but not `myapp.com`
182
+
3.**AllowedHostsFunc** — called only if no static rule matched
180
183
181
184
The first match wins. If nothing matches, `ErrorHandler` is called.
182
185
183
186
## Host Normalization
184
187
185
-
Before matching, the incoming host is normalized:
188
+
Before matching, both incoming hosts and `AllowedHosts` entries are normalized at startup:
186
189
187
-
- Port is stripped (via `c.Hostname()`)
190
+
- Port is stripped (`example.com:8080` → `example.com`)
- IDN labels converted to ASCII/Punycode (`münchen.example.com` → `xn--mnchen-3ya.example.com`)
195
+
- RFC 1035 length limits enforced at startup: ≤253 chars total, ≤63 chars per label (panic on violation)
196
+
197
+
## Filtering by Client IP
191
198
192
-
`AllowedHosts` entries are also lowercased at initialization.
199
+
This middleware filters by the `Host`*header*, not by the client's source IP. To restrict access by client IP, use Fiber's [`TrustProxy` / `TrustProxyConfig`](https://docs.gofiber.io/whats_new#trusted-proxies) configuration — those are the correct knobs for IP allowlisting and CIDR ranges of trusted proxies.
193
200
194
201
## Proxy Support
195
202
@@ -202,6 +209,7 @@ fasthttp itself is HTTP/1.x only. HTTP/2 support requires an external library (e
202
209
-**RFC 9110 Section 7.2** — Host and port are separate components; port is stripped before matching
0 commit comments