The web/cors package provides CORS middleware with credential-safety validation and explicit origin allowlisting.

Import

Configuration

AllowedOrigins

An explicit allowlist of origins. Wildcards ("*") are supported only when AllowCredentials is false — the constructor returns an error for the insecure combination.
"null" is the origin sent by sandboxed iframes, data: URLs, and file:// pages, and is trivially spoofable — allow-listing it together with credentials is exactly as dangerous as the wildcard, so cors.New rejects that combination too.

Dynamic origin check

For multi-tenant setups where the allowed origins are not a static list, set OriginFunc. When set, it overrides AllowedOrigins entirely.

AllowedHeaders

Headers the browser may send on the preflight response. When AllowedHeaders is empty, the middleware mirrors whatever the browser requested via Access-Control-Request-Headers (sanitized to valid header tokens). When AllowedHeaders is set, it is sent verbatim instead — nothing is auto-injected, so if your app relies on Content-Type or another header being implicitly allowed, list it explicitly:

ExposedHeaders

Headers the browser may read from the response:

MaxAge

MaxAge is a time.Duration, not a bare number of seconds — write it as a duration expression (e.g. 86400 * time.Second). It caches the preflight response for that long, reducing unnecessary OPTIONS requests. Default: 0 (no Access-Control-Max-Age header sent). Browser maximum is typically 7200 (2 hours) or 86400 (24 hours) seconds.

Preflight handling

OPTIONS preflight requests are handled entirely by the CORS middleware and always answered with 204 No Content — never reaching your handler, whether the origin is allowed or not.