Cors Wildcard in Buffalo with Hmac Signatures
Cors Wildcard in Buffalo with Hmac Signatures — how this specific combination creates or exposes the vulnerability
In Buffalo, using a CORS wildcard (Access-Control-Allow-Origin: *) together with Hmac Signatures for request authentication can unintentionally expose a critical security risk by allowing unauthorized origins to participate in the signed flow. When the server sets an unrestricted CORS header while also relying on Hmac Signatures to validate request integrity, it may still process requests from any origin, but the browser’s same-origin policy enforcement is weakened. This combination can enable cross-origin attackers to trick a victim’s browser into making authenticated requests that appear valid because the Hmac Signature is computed correctly, yet the origin is not explicitly trusted.
Buffalo applications typically set CORS configuration in actions/app.go. If the configuration permits all origins with a wildcard, and the application middleware validates Hmac Signatures but does not also enforce an allowlist of origins, the server may reflect or process requests from malicious sites. An attacker can craft a form or script on a different origin that includes the necessary headers and body parameters; if the server’s Hmac verification only checks the signature correctness without origin checks, the request can be executed in the context of the victim’s session (CSRF-like behavior enabled by permissive CORS).
Hmac Signatures are designed to ensure that the request payload and headers have not been altered. However, if the server’s CORS policy is a wildcard, preflight requests (OPTIONS) will succeed for any origin, and the actual request can carry the Authorization or custom headers that the server’s Hmac validation accepts. This means the attacker does not need to know the secret key; they rely on the victim’s authenticated session and the server’s willingness to process requests from any origin. The vulnerability is not in Hmac itself but in the lack of origin restriction when combined with wildcard CORS, which removes a layer of enforcement that would otherwise limit which domains can participate in the signed exchange.
During a middleBrick scan, such misconfigurations are surfaced in the Authentication and BOLA/IDOR checks, highlighting that the exposed endpoint accepts requests from untrusted origins despite using Hmac Signatures. The scanner’s Inventory Management and Unsafe Consumption checks may further indicate that the API’s security posture depends on correct CORS settings, and the absence of an explicit origin allowlist weakens the overall protection provided by Hmac Signatures.
Hmac Signatures-Specific Remediation in Buffalo — concrete code fixes
To remediate the risk, restrict CORS to specific trusted origins and ensure Hmac Signature validation includes origin verification. Below are concrete code examples for a Buffalo application written in Go, demonstrating how to configure CORS and validate Hmac Signatures safely.
1. Configure CORS with an allowlist instead of a wildcard
Update your CORS settings to permit only known origins. In actions/app.go, use a predefined list of origins.
package actions
import (
"github.com/gobuffalo/buffalo"
"github.com/gobuffalo/buffalo/middleware"
)
func App() *buffalo.App {
if app == nil {
app = buffalo.New(buffalo.Options{
Middleware: []buffalo.MiddlewareFunc{
// Configure CORS with specific origins
middleware.CORS(&middleware.CORSOptions{
AllowedOrigins: []string{"https://app.example.com", "https://admin.example.com"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE"},
AllowedHeaders: []string{"Authorization", "Content-Type", "X-Request-ID"},
ExposedHeaders: []string{"X-Request-ID"},
AllowCredentials: true,
}),
middleware.ParamsParser,
// other middleware...
},
})
}
return app
}
2. Validate Hmac Signature and include origin check
When verifying Hmac Signatures, ensure the request origin is in the allowed list before performing signature validation. This prevents a malicious origin from leveraging a valid signature issued for a trusted origin.
package middleware
import (
"net/http"
"strings"
"github.com/gobuffalo/buffalo"
"github.com/gobuffalo/buffalo/context"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
)
func HmacSignature(next buffalo.Handler) buffalo.Handler {
return func(c *context.Context) error {
origin := c.Request.Header.Get("Origin")
allowedOrigins := map[string]bool{
"https://app.example.com": true,
"https://admin.example.com": true,
}
if !allowedOrigins[origin] {
c.Response.WriteHeader(http.StatusForbidden)
return nil
}
secret := []byte(os.Getenv("HMAC_SECRET"))
payload := c.Request.Header.Get("X-Payload")
receivedSig := c.Request.Header.Get("X-Signature")
mac := hmac.New(sha256.New, secret)
mac.Write([]byte(payload))
expectedSig := hex.EncodeToString(mac.Sum(nil))
if !hmac.Equal([]byte(expectedSig), []byte(receivedSig)) {
c.Response.WriteHeader(http.StatusUnauthorized)
return nil
}
return next(c)
}
}
3. Combine CORS middleware ordering and secure defaults
Place the CORS middleware before your Hmac Signature validation so that origin rejection happens early. Also, avoid using * in AllowedOrigins when Hmac Signatures are in use, and ensure that sensitive headers are not inadvertently exposed.
func App() *buffalo.App {
if app == nil {
app = buffalo.New(buffalo.Options{
Middleware: []buffalo.MiddlewareFunc{
// CORS first to reject unauthorized origins
middleware.CORS(&middleware.CORSOptions{
AllowedOrigins: []string{"https://app.example.com", "https://admin.example.com"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE"},
AllowedHeaders: []string{"Authorization", "Content-Type", "X-Request-ID"},
ExposedHeaders: []string{"X-Request-ID"},
AllowCredentials: true,
}),
// Then security middleware that validates Hmac Signatures
HmacSignature,
middleware.ParamsParser,
},
})
}
return app
}
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 |