Skip to main content
Version: Next

CORS

CORS (Cross-Origin Resource Sharing) is a middleware for Fiber that allows servers to specify who can access its resources and how. It's not a security feature, but a way to relax the security model of web browsers for cross-origin requests. You can learn more about CORS on Mozilla Developer Network.

This middleware works by adding CORS headers to responses from your Fiber application. These headers specify which origins, methods, and headers are allowed for cross-origin requests. It also handles preflight requests, which are a CORS mechanism to check if the actual request is safe to send.

The middleware uses the AllowOrigins option to control which origins can make cross-origin requests. It supports single origin, multiple origins, subdomain matching, and wildcard origin. It also allows programmatic origin validation with the AllowOriginsFunc option.

To ensure that the provided AllowOrigins origins are correctly formatted, this middleware validates and normalizes them. It checks for valid schemes, i.e., HTTP or HTTPS, and it will automatically remove trailing slashes. If the provided origin is invalid, the middleware will panic.

When configuring CORS, it's important to avoid common pitfalls like using a wildcard origin with credentials, being overly permissive with origins, and inadequate validation with AllowOriginsFunc. Misconfiguration can expose your application to various security risks.

Signatures

func New(config ...Config) fiber.Handler

Examples

Import the middleware package that is part of the Fiber web framework

import (
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/cors"
)

After you initiate your Fiber app, you can use the following possibilities:

Basic usage

To use the default configuration, simply use cors.New(). This will allow wildcard origins '*', all methods, no credentials, and no headers or exposed headers.

app.Use(cors.New())

Custom configuration (specific origins, headers, etc.)

// Initialize default config
app.Use(cors.New())

// Or extend your config for customization
app.Use(cors.New(cors.Config{
AllowOrigins: []string{"https://gofiber.io", "https://gofiber.net"},
AllowHeaders: []string{"Origin", "Content-Type", "Accept"},
}))

Dynamic origin validation

You can use AllowOriginsFunc to programmatically determine whether to allow a request based on its origin. This is useful when you need to validate origins against a database or other dynamic sources. The function should return true if the origin is allowed, and false otherwise.

Be sure to review the security considerations when using AllowOriginsFunc.

caution

Never allow AllowOriginsFunc to return true for all origins. This is particularly crucial when AllowCredentials is set to true. Doing so can bypass the restriction of using a wildcard origin with credentials, exposing your application to serious security threats.

If you need to allow wildcard origins, use AllowOrigins with a wildcard "*" instead of AllowOriginsFunc.

// dbCheckOrigin checks if the origin is in the list of allowed origins in the database.
func dbCheckOrigin(db *sql.DB, origin string) bool {
// Placeholder query - adjust according to your database schema and query needs
query := "SELECT COUNT(*) FROM allowed_origins WHERE origin = $1"

var count int
err := db.QueryRow(query, origin).Scan(&count)
if err != nil {
// Handle error (e.g., log it); for simplicity, we return false here
return false
}

return count > 0
}

// ...

app.Use(cors.New(cors.Config{
AllowOriginsFunc: func(origin string) bool {
return dbCheckOrigin(db, origin)
},
}))

Prohibited usage

The following example is prohibited because it can expose your application to security risks. It sets AllowOrigins to "*" (a wildcard) and AllowCredentials to true.

app.Use(cors.New(cors.Config{
AllowOrigins: []string{"*"},
AllowCredentials: true,
}))

This will result in the following panic:

panic: [CORS] Configuration error: When 'AllowCredentials' is set to true, 'AllowOrigins' cannot contain a wildcard origin '*'. Please specify allowed origins explicitly or adjust 'AllowCredentials' setting.

Config

PropertyTypeDescriptionDefault
AllowCredentialsboolAllowCredentials indicates whether or not the response to the request can be exposed when the credentials flag is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note: If true, AllowOrigins cannot be set to a wildcard ("*") to prevent security vulnerabilities.false
AllowHeaders[]stringAllowHeaders defines a list of request headers that can be used when making the actual request. This is in response to a preflight request.[]
AllowMethods[]stringAllowMethods defines a list of methods allowed when accessing the resource. This is used in response to a preflight request."GET, POST, HEAD, PUT, DELETE, PATCH"
AllowOrigins[]stringAllowOrigins defines a list of origins that may access the resource. This supports subdomain matching, so you can use a value like "https://*.example.com" to allow any subdomain of example.com to submit requests. If the special wildcard "*" is present in the list, all origins will be allowed.["*"]
AllowOriginsFuncfunc(origin string) boolAllowOriginsFunc is a function that dynamically determines whether to allow a request based on its origin. If this function returns true, the 'Access-Control-Allow-Origin' response header will be set to the request's 'origin' header. This function is only used if the request's origin doesn't match any origin in AllowOrigins.nil
AllowPrivateNetworkboolIndicates whether the Access-Control-Allow-Private-Network response header should be set to true, allowing requests from private networks. This aligns with modern security practices for web applications interacting with private networks.false
ExposeHeadersstringExposeHeaders defines an allowlist of headers that clients are allowed to access.[]
MaxAgeintMaxAge indicates how long (in seconds) the results of a preflight request can be cached. If you pass MaxAge 0, the Access-Control-Max-Age header will not be added and the browser will use 5 seconds by default. To disable caching completely, pass MaxAge value negative. It will set the Access-Control-Max-Age header to 0.0
Nextfunc(fiber.Ctx) boolNext defines a function to skip this middleware when returned true.nil
note

If AllowOrigins is a zero value []string{}, and AllowOriginsFunc is provided, the middleware will not default to allowing all origins with the wildcard value "*". Instead, it will rely on the AllowOriginsFunc to dynamically determine whether to allow a request based on its origin. This provides more flexibility and control over which origins are allowed.

Default Config

var ConfigDefault = Config{
Next: nil,
AllowOriginsFunc: nil,
AllowOrigins: []string{"*"},
AllowMethods: []string{
fiber.MethodGet,
fiber.MethodPost,
fiber.MethodHead,
fiber.MethodPut,
fiber.MethodDelete,
fiber.MethodPatch,
},
AllowHeaders: []string{},
AllowCredentials: false,
ExposeHeaders: []string{},
MaxAge: 0,
AllowPrivateNetwork: false,
}

Subdomain Matching

The AllowOrigins configuration supports matching subdomains at any level. This means you can use a value like "https://*.example.com" to allow any subdomain of example.com to submit requests, including multiple subdomain levels such as "https://sub.sub.example.com".

Example

If you want to allow CORS requests from any subdomain of example.com, including nested subdomains, you can configure the AllowOrigins like so:

app.Use(cors.New(cors.Config{
AllowOrigins: "https://*.example.com",
}))

How It Works

The CORS middleware works by adding the necessary CORS headers to responses from your Fiber application. These headers tell browsers what origins, methods, and headers are allowed for cross-origin requests.

When a request comes in, the middleware first checks if it's a preflight request, which is a CORS mechanism to determine whether the actual request is safe to send. Preflight requests are HTTP OPTIONS requests with specific CORS headers. If it's a preflight request, the middleware responds with the appropriate CORS headers and ends the request.

If it's not a preflight request, the middleware adds the CORS headers to the response and passes the request to the next handler. The actual CORS headers added depend on the configuration of the middleware.

The AllowOrigins option controls which origins can make cross-origin requests. The middleware handles different AllowOrigins configurations as follows:

  • Single origin: If AllowOrigins is set to a single origin like "http://www.example.com", and that origin matches the origin of the incoming request, the middleware adds the header Access-Control-Allow-Origin: http://www.example.com to the response.

  • Multiple origins: If AllowOrigins is set to multiple origins like "https://example.com, https://www.example.com", the middleware picks the origin that matches the origin of the incoming request.

  • Subdomain matching: If AllowOrigins includes "https://*.example.com", a subdomain like https://sub.example.com will be matched and "https://sub.example.com" will be the header. This will also match https://sub.sub.example.com and so on, but not https://example.com.

  • Wildcard origin: If AllowOrigins is set to "*", the middleware uses that and adds the header Access-Control-Allow-Origin: * to the response.

In all cases above, except the Wildcard origin, the middleware will either add the Access-Control-Allow-Origin header to the response matching the origin of the incoming request, or it will not add the header at all if the origin is not allowed.

  • Programmatic origin validation:: The middleware also handles the AllowOriginsFunc option, which allows you to programmatically determine if an origin is allowed. If AllowOriginsFunc returns true for an origin, the middleware sets the Access-Control-Allow-Origin header to that origin.

The AllowMethods option controls which HTTP methods are allowed. For example, if AllowMethods is set to "GET, POST", the middleware adds the header Access-Control-Allow-Methods: GET, POST to the response.

The AllowHeaders option specifies which headers are allowed in the actual request. The middleware sets the Access-Control-Allow-Headers response header to the value of AllowHeaders. This informs the client which headers it can use in the actual request.

The AllowCredentials option indicates whether the response to the request can be exposed when the credentials flag is true. If AllowCredentials is set to true, the middleware adds the header Access-Control-Allow-Credentials: true to the response. To prevent security vulnerabilities, AllowCredentials cannot be set to true if AllowOrigins is set to a wildcard (*).

The ExposeHeaders option defines an allowlist of headers that clients are allowed to access. If ExposeHeaders is set to "X-Custom-Header", the middleware adds the header Access-Control-Expose-Headers: X-Custom-Header to the response.

The MaxAge option indicates how long the results of a preflight request can be cached. If MaxAge is set to 3600, the middleware adds the header Access-Control-Max-Age: 3600 to the response.

The Vary header is used in this middleware to inform the client that the server's response to a request. For or both preflight and actual requests, the Vary header is set to Access-Control-Request-Method and Access-Control-Request-Headers. For preflight requests, the Vary header is also set to Origin. The Vary header is important for caching. It helps caches (like a web browser's cache or a CDN) determine when a cached response can be used in response to a future request, and when the server needs to be queried for a new response.

Security Considerations

When configuring CORS, misconfiguration can potentially expose your application to various security risks. Here are some secure configurations and common pitfalls to avoid:

Secure Configurations

  • Specify Allowed Origins: Instead of using a wildcard ("*"), specify the exact domains allowed to make requests. For example, AllowOrigins: "https://www.example.com, https://api.example.com" ensures only these domains can make cross-origin requests to your application.

  • Use Credentials Carefully: If your application needs to support credentials in cross-origin requests, ensure AllowCredentials is set to true and specify exact origins in AllowOrigins. Do not use a wildcard origin in this case.

  • Limit Exposed Headers: Only allowlist headers that are necessary for the client-side application by setting ExposeHeaders appropriately. This minimizes the risk of exposing sensitive information.

Common Pitfalls

  • Wildcard Origin with Credentials: Setting AllowOrigins to "*" (a wildcard) and AllowCredentials to true is a common misconfiguration. This combination is prohibited because it can expose your application to security risks.

  • Overly Permissive Origins: Specifying too many origins or using overly broad patterns (e.g., https://*.example.com) can inadvertently allow malicious sites to interact with your application. Be as specific as possible with allowed origins.

  • Inadequate AllowOriginsFunc Validation: When using AllowOriginsFunc for dynamic origin validation, ensure the function includes robust checks to prevent unauthorized origins from being accepted. Overly permissive validation can lead to security vulnerabilities. Never allow AllowOriginsFunc to return true for all origins. This is particularly crucial when AllowCredentials is set to true. Doing so can bypass the restriction of using a wildcard origin with credentials, exposing your application to serious security threats. If you need to allow wildcard origins, use AllowOrigins with a wildcard "*" instead of AllowOriginsFunc.

Remember, the key to secure CORS configuration is specificity and caution. By carefully selecting which origins, methods, and headers are allowed, you can help protect your application from cross-origin attacks.