Cors Wildcard in Gin
How Cors Wildcard Manifests in Gin
Cors Wildcard vulnerabilities in Gin applications typically arise when developers configure CORS (Cross-Origin Resource Sharing) with overly permissive settings, particularly using wildcard origins (*) or methods. This manifests in several specific ways within Gin applications.
The most common manifestation occurs when developers use Gin's cors.New middleware with wildcard configurations. For example:
router := gin.Default()
router.Use(cors.New(cors.Config{
AllowOrigins: "*",
AllowMethods: "*",
AllowHeaders: "*",
AllowCredentials: true, // Critical misconfiguration
}))This configuration appears benign but creates a severe security vulnerability. The combination of wildcard origins with AllowCredentials: true violates the CORS specification, which explicitly forbids returning credentials for wildcard origins. Browsers will reject this configuration, but the server still processes the request, creating an inconsistent security boundary.
In Gin applications, this vulnerability often appears in API endpoints that should be restricted to specific origins. Consider a Gin handler that processes sensitive operations:
router.POST("/api/admin", cors.Default(), func(c *gin.Context) {
// Admin operations without proper origin validation
var payload AdminPayload
if err := c.ShouldBindJSON(&payload); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Process admin action
processAdminAction(payload)
c.JSON(http.StatusOK, gin.H{"status": "success"})
})Without proper CORS validation, any website can make authenticated requests to this endpoint, bypassing the browser's same-origin policy. The vulnerability is particularly dangerous in Gin applications because the framework's middleware execution order can sometimes mask these issues during development.
Another Gin-specific manifestation involves improper use of the gin.Context object for CORS handling. Developers might manually set CORS headers without using the proper middleware:
router.GET("/api/data", func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
c.JSON(http.StatusOK, getData())
})This approach fails to handle preflight requests (OPTIONS) and doesn't properly validate the Origin header against the request's actual source, creating a security gap that attackers can exploit.
Gin-Specific Detection
Detecting CORS wildcard vulnerabilities in Gin applications requires both manual code review and automated scanning approaches. The most effective detection combines static analysis of the source code with dynamic runtime testing.
Static detection involves searching for specific patterns in your Gin codebase. Look for these red flags:
// Search for these patterns:
cors.New(cors.Config{AllowOrigins: "*"})
cors.Default()
cors.Config{AllowMethods: "*"}
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Credentials", "true")Pay special attention to configurations where AllowCredentials: true appears alongside wildcard origins. This combination is always a security violation. Also check for hardcoded wildcard origins in configuration files or environment variables.
Dynamic detection with middleBrick provides comprehensive coverage that static analysis might miss. middleBrick's CORS scanner specifically tests for wildcard configurations by:
- Sending requests with various Origin headers to detect wildcard responses
- Testing the AllowCredentials combination with wildcard origins
- Verifying proper handling of preflight OPTIONS requests
- Checking for inconsistent CORS header implementations
When scanning a Gin API with middleBrick, the tool will identify specific endpoints vulnerable to CORS wildcard attacks and provide a security score based on the severity of the misconfiguration. The scanner tests the unauthenticated attack surface, making it particularly effective for identifying publicly exposed API endpoints with CORS issues.
For Gin applications specifically, middleBrick's detection includes verification that CORS middleware is properly configured and applied to all relevant routes. The scanner checks whether the CORS configuration matches the security requirements of each endpoint, flagging cases where sensitive operations lack proper origin validation.
Gin-Specific Remediation
Remediating CORS wildcard vulnerabilities in Gin applications requires a systematic approach to tighten CORS policies while maintaining legitimate cross-origin functionality. The primary goal is to replace wildcard configurations with specific, trusted origins.
The most secure approach is to explicitly define allowed origins:
allowedOrigins := []string{
"https://yourdomain.com",
"https://yourapi.com",
"https://yourapp.com",
}
router.Use(cors.New(cors.Config{
AllowOrigins: allowedOrigins,
AllowMethods: "GET, POST, PUT, DELETE, OPTIONS",
AllowHeaders: "Origin, Content-Type, Authorization, Accept",
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}))This configuration ensures only specified origins can access your API. For Gin applications that need to support multiple environments, consider using environment-specific configurations:
func getCorsConfig() cors.Config {
allowedOrigins := os.Getenv("CORS_ALLOWED_ORIGINS")
if allowedOrigins == "" {
// Default to development origins
allowedOrigins = "http://localhost:3000,http://localhost:8080"
}
originsList := strings.Split(allowedOrigins, ",")
return cors.Config{
AllowOrigins: originsList,
AllowMethods: "GET, POST, PUT, DELETE, OPTIONS",
AllowHeaders: "Origin, Content-Type, Authorization, Accept",
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}
}
router.Use(cors.New(getCorsConfig()))For Gin applications with sensitive endpoints, implement additional origin validation at the handler level:
func validateOrigin(c *gin.Context, allowed []string) bool {
origin := c.GetHeader("Origin")
for _, allowedOrigin := range allowed {
if origin == allowedOrigin {
return true
}
}
return false
}
router.POST("/api/sensitive", cors.Default(), func(c *gin.Context) {
if !validateOrigin(c, []string{"https://trusted.com"}) {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "Origin not allowed"})
return
}
// Process sensitive operation
})Another Gin-specific remediation involves using middleware chains to apply different CORS policies to different route groups:
publicGroup := router.Group("/public")
{
publicGroup.Use(cors.New(cors.Config{
AllowOrigins: []string{"*"}, // Public endpoints can use wildcard
AllowMethods: "GET, OPTIONS",
}))
publicGroup.GET("/open-data", openDataHandler)
}
secureGroup := router.Group("/api")
{
secureGroup.Use(cors.New(cors.Config{
AllowOrigins: []string{"https://yourapp.com"},
AllowCredentials: true,
}))
secureGroup.POST("/admin", adminHandler)
}This approach provides the principle of least privilege by applying strict CORS policies to sensitive endpoints while maintaining accessibility for public resources.
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 |