Cors Wildcard in Gorilla Mux with Hmac Signatures
Cors Wildcard in Gorilla Mux with Hmac Signatures — how this specific combination creates or exposes the vulnerability
A CORS wildcard (Access-Control-Allow-Origin: *) combined with Hmac Signature validation in a Gorilla Mux router creates a critical mismatch between origin trust and integrity verification. When the server responds with a wildcard, any origin can read the response, but the client must still present a valid Hmac signature to access the endpoint. The vulnerability arises because the browser enforces CORS before allowing JavaScript to read the response, while non-browser clients (e.g., curl, scripts) can ignore CORS entirely and still verify Hmac signatures if the secret is leaked or weak.
In Gorilla Mux, handlers often set CORS headers per route. If a route uses router.HandleFunc("/api/data", dataHandler).Methods("GET") and the handler sets w.Header().Set("Access-Control-Allow-Origin", "*"), the endpoint is exposed to any frontend. An attacker’s page can invoke the request in an iframe or via fetch, observe whether the request is allowed by CORS, and then attempt to replay the request with a stolen or predictable Hmac signature. If the Hmac is computed over a subset of headers or a weak nonce, the signature can be forged. This combination—permissive CORS plus brittle Hmac integrity—enables cross-origin discovery of valid signatures and opens the door to unauthorized actions on behalf of authenticated users.
Moreover, preflight requests (OPTIONS) may also reflect the wildcard, signaling to an attacker that CORS is unrestricted while the server still expects Hmac-signed requests. If the Hmac signing process is not constant-time, timing attacks can further weaken the scheme. For example, an attacker can measure response times to infer whether a partial signature matches. Because Gorilla Mux does not enforce origin constraints when a wildcard is set, the integrity provided by Hmac signatures is effectively bypassed for malicious origins that can trick a victim into making signed requests.
Real-world parallels include findings where APIs used * for CORS while relying on custom token schemes, leading to privilege escalation via compromised browser contexts. In the API security checks run by middleBrick, such configurations appear as BOLA/IDOR and CORS misconfigurations, with remediation tied to strict origin policies and robust signature construction. The scanner highlights that permissive COBRAS-style wildcard settings neutralize the protective intent of Hmac-based integrity checks.
Hmac Signatures-Specific Remediation in Gorilla Mux — concrete code fixes
To remediate, enforce a specific Access-Control-Allow-Origin value that matches your frontend origins rather than using a wildcard. Combine this with strict validation of the Hmac signature on every request, ensuring the signature covers critical headers and the request method/URL path.
Secure Gorilla Mux Setup with Hmac Signatures
Below is a complete, working example for Gorilla Mux that demonstrates secure CORS and Hmac verification.
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"net/http"
"strings"
"github.com/gorilla/mux"
)
var signingKey = []byte("your-256-bit-secret-32-bytes-long-12345678")
func computeHmac(payload string) string {
h := hmac.New(sha256.New, signingKey)
h.Write([]byte(payload))
return hex.EncodeToString(h.Sum(nil))
}
func secureHandler(w http.ResponseWriter, r *http.Request) {
// Expected signature is passed in a custom header
sigHeader := r.Header.Get("X-API-Signature")
if sigHeader == "" {
http.Error(w, "missing signature", http.StatusUnauthorized)
return
}
// Reconstruct the signed payload: method + path + selected headers
payload := r.Method + r.RequestURI
expected := computeHmac(payload)
if !hmac.Equal([]byte(expected), []byte(sigHeader)) {
http.Error(w, "invalid signature", http.StatusForbidden)
return
}
// Set strict CORS: specific origin, not wildcard
w.Header().Set("Access-Control-Allow-Origin", "https://app.yourdomain.com")
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, X-API-Signature")
w.Header().Set("Access-Control-Expose-Headers", "X-Rate-Limit-Limit")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
w.Write([]byte("secure data"))
}
func main() {
r := mux.NewRouter()
// Apply CORS and Hmac checks to the route
r.HandleFunc("/api/data", secureHandler).Methods("GET", "OPTIONS")
http.ListenAndServe(":8080", r)
}
Key points in this remediation:
- Replace
Access-Control-Allow-Origin: *with explicit origins such ashttps://app.yourdomain.com. For multiple origins, implement dynamic origin checking against an allowlist. - Include the request method and request URI in the Hmac payload to prevent method tampering and path confusion.
- Use
hmac.Equalfor constant-time comparison to mitigate timing attacks. - Require the signature in a custom header (
X-API-Signature) and ensure it is validated before any business logic executes. - Handle preflight (
OPTIONS) separately and do not rely on the wildcard for CORS when signatures are involved.
In a CI/CD context, the middleBrick CLI can be integrated to scan these routes and flag wildcard CORS alongside weak signature schemes. Using the GitHub Action, you can fail builds if such risky patterns are detected before deployment.
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 |