HIGH cors wildcardginapi keys

Cors Wildcard in Gin with Api Keys

Cors Wildcard in Gin with Api Keys — how this specific combination creates or exposes the vulnerability

In Gin, using a CORS wildcard with API key authentication creates a security misconfiguration where unauthorized origins can leverage credentials-bearing requests. When app.Use(cors.New(cors.Config{AllowOrigins: []string{"*"}}) is combined with API key validation via middleware such as apikey middleware, the browser may send credentials (cookies, authorization headers) to a wildcard origin if the request includes the API key in a header like X-API-Key. This violates the same-origin policy intent because the wildcard permits any domain to make authenticated requests, effectively exposing the API key–protected endpoint to cross-origin attackers who can trick a victim’s browser into issuing requests on their behalf.

For example, consider a Gin route protected by API key middleware:

gin.Default()
   .Use(cors.New(cors.Config{AllowOrigins: []string{"*"}}))
   .Use(ApiKeyMiddleware())
   .GET("/admin", handler)

An attacker crafts a page on evil.com that loads an image or script from https://api.example.com/admin with the X-API-Key header injected via a preflighted request. If the API key is leaked via Referer or if the endpoint returns sensitive data, the attacker can harvest it. The CORS preflight response with Access-Control-Allow-Origin: * and Access-Control-Allow-Credentials: true is disallowed together in browsers, but many Gin setups use AllowCredentials: true with a wildcard origin, which browsers reject; however, non-browser clients (e.g., compromised servers or misconfigured SDKs) can still make authenticated cross-origin requests, bypassing browser protections and exposing the API key in logs or error messages.

This pattern also interacts poorly with OWASP API Top 10 controls: improper authentication (broken object level authorization when origin is unrestricted) and excessive data exposure (sensitive payloads returned to untrusted origins). A misconfigured wildcard can amplify risks found in other 12 checks, such as input validation flaws that allow header smuggling to spoof the API key origin. Real-world analogues include CVE scenarios where missing origin validation paired with bearer or static key authentication leads to token exfiltration via malicious web pages.

Api Keys-Specific Remediation in Gin — concrete code fixes

Remediate by replacing the CORS wildcard with an allowlist of trusted origins and enforcing strict alignment between CORS credentials settings and API key usage. In Gin, use a named origin list and set AllowCredentials only when necessary, ensuring that API key validation occurs before CORS preflight handling. Below is a secure configuration example:

c := cors.New(cors.Config{
    AllowOrigins:   []string{"https://trusted.example.com", "https://app.example.com"},
    AllowMethods:   []string{"GET", "POST", "PUT", "DELETE"},
    AllowHeaders:   []string{"Content-Type", "Authorization", "X-API-Key"},
    ExposeHeaders:  []string{"Content-Length"},
    AllowCredentials: true,
    MaxAge: 12 * time.Hour,
})
app.Use(c)
app.Use(ApiKeyMiddleware())
app.GET("/admin", handler)

The ApiKeyMiddleware should validate the key from a secure source (e.g., environment variable) and reject requests missing or mismatching the key:

func ApiKeyMiddleware() gin.HandlerFunc {
    apiKey := os.Getenv("API_KEY")
    return func(c *gin.Context) {
        key := c.GetHeader("X-API-Key")
        if key != apiKey {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid api key"})
            return
        }
        c.Next()
    }
}

If you must support credentialed cross-origin requests, keep AllowCredentials: true but specify exact origins; avoid wildcard origins. For public endpoints that do not require credentials, disable AllowCredentials and keep the wildcard for static assets, but ensure API key–protected routes are under a separate middleware group with stricter CORS rules:

publicGroup := app.Group("/public")
publicGroup.Use(cors.New(cors.Config{
    AllowOrigins: []string{"*"},
    AllowMethods: []string{"GET"},
    AllowHeaders: []string{"Accept"},
    AllowCredentials: false,
}))
publicGroup.GET("/health", healthHandler)

secureGroup := app.Group("/secure")
secureGroup.Use(cors.New(cors.Config{
    AllowOrigins: []string{"https://trusted.example.com"},
    AllowMethods: []string{"POST"},
    AllowHeaders: []string{"Content-Type", "X-API-Key"},
    AllowCredentials: true,
}))
secureGroup.Use(ApiKeyMiddleware())
secureGroup.GET("/data", dataHandler)

These patterns reduce the attack surface by ensuring that API key validation and CORS policies are aligned, preventing unauthorized cross-origin authenticated requests and mitigating the risk of key leakage via malicious sites.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Is it safe to use AllowCredentials: true with a CORS wildcard in Gin?
No. Browsers reject the combination of Access-Control-Allow-Origin: * and Access-Control-Allow-Credentials: true; however, non-browser clients can still make authenticated cross-origin requests, exposing API keys. Use an explicit allowlist of origins instead.
How can I verify that my API key middleware is effective against cross-origin attacks?
Test with requests from unauthorized origins including preflight (OPTIONS) requests and verify that responses do not expose keys and that CORS headers do not permit wildcard origins when credentials are required. Combine with scanning tools that check CORS and authentication configurations.