Cors Wildcard in Gin with Bearer Tokens
Cors Wildcard in Gin with Bearer Tokens — how this combination creates or exposes the vulnerability
In Gin, configuring CORS with a wildcard origin (*) while also using Bearer token authentication can unintentionally expose protected endpoints to unauthorized origins. A wildcard CORS policy allows any origin to make requests and include credentials such as cookies or authorization headers, depending on how the middleware is set up. When AllowCredentials is enabled alongside AllowOrigins set to *, browsers may permit cross-origin requests to include the Authorization header containing the Bearer token, even if the endpoint is intended for authenticated use only.
This combination becomes a vulnerability when an origin that should not be trusted is able to include a valid Bearer token in a cross-origin request. If an attacker controls a web page served from another origin and can trick a user who is authenticated into making a request, the attacker may be able to perform actions on behalf of the user. The presence of the Bearer token in the Authorization header means the request is treated as authenticated, and CORS settings that allow credentials with a wildcard origin remove the same-origin policy protection that would otherwise block such cross-origin authenticated requests.
Gin’s CORS implementation does not treat * as a wildcard when credentials are allowed; instead, the server must explicitly list allowed origins. However, developers sometimes use * for convenience during development or misconfigure production settings, believing that token-based authentication alone is sufficient. In reality, CORS is a browser-enforced mechanism, and if misconfigured, it can bypass intended access controls. For example, an endpoint expecting a Bearer token in the Authorization header may still process requests from any origin if CORS allows credentials, enabling cross-origin authenticated calls that should be restricted.
Additionally, preflight requests can reveal whether CORS is permissive. An OPTIONS request with headers such as Access-Control-Request-Headers: authorization may return an Access-Control-Allow-Origin: * response with credentials permitted, signaling to an attacker that cross-origin authenticated requests are possible. This misconfiguration does not directly leak tokens, but it weakens the boundary between authenticated clients and unauthorized origins, increasing the risk of token misuse in cross-origin contexts.
For accurate scanning of such issues, tools like middleBrick can analyze the unauthenticated attack surface of a Gin service, including CORS headers and authentication mechanisms. The scanner checks whether credentials are allowed with a wildcard origin and flags risky combinations that could allow unauthorized cross-origin authenticated requests, helping teams identify misconfigurations before they are exploited.
Bearer Tokens-Specific Remediation in Gin — concrete code fixes
To remediate CORS misconfigurations with Bearer tokens in Gin, explicitly define allowed origins instead of using * when credentials or authorization headers are involved. The following example demonstrates a secure CORS setup that allows a specific origin and permits the Authorization header, while avoiding wildcard origins in production.
import (
"github.com/gin-gonic/gin"
"github.com/gin-contrib/cors"
)
func main() {
r := gin.Default()
config := cors.Config{
AllowOrigins: []string{"https://app.example.com"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Authorization", "Content-Type"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 12 * 3600,
}
r.Use(cors.New(config))
r.GET("/profile", func(c *gin.Context) {
auth := c.GetHeader("Authorization")
if auth == "" {
c.AbortWithStatusJSON(401, gin.H{"error": "authorization header required"})
return
}
// Validate Bearer token here
c.JSON(200, gin.H{"message": "profile"})
})
r.Run()
}
If you need to support multiple trusted origins, list them explicitly rather than using a wildcard. The following configuration shows how to allow multiple specific origins while still permitting Bearer tokens via the Authorization header.
config := cors.Config{
AllowOrigins: []string{"https://app.example.com", "https://dashboard.example.com"},
AllowMethods: []string{"GET", "POST", "OPTIONS"},
AllowHeaders: []string{"Authorization", "Content-Type"},
AllowCredentials: true,
MaxAge: 12 * 3600,
}
For development or testing, you may conditionally apply a more permissive CORS policy based on environment variables, ensuring that production configurations remain strict.
import "os"
var allowedOrigins []string
if os.Getenv("ENV") == "production" {
allowedOrigins = []string{"https://app.example.com"}
} else {
allowedOrigins = []string{"http://localhost:3000", "http://127.0.0.1:8080"}
}
config := cors.Config{
AllowOrigins: allowedOrigins,
AllowMethods: []string{"GET", "POST", "OPTIONS"},
AllowHeaders: []string{"Authorization", "Content-Type"},
AllowCredentials: true,
MaxAge: 12 * 3600,
}
When using middleBrick, you can verify that your Gin service does not expose wildcard origins with enabled credentials by running a scan against the endpoint. The tool reports CORS-related misconfigurations and maps findings to frameworks such as OWASP API Top 10, helping prioritize remediation for token-based authentication flaws.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |