Fix Insecure Webhooks in Beego
Webhooks in Beego are often implemented as wide-open endpoints that trust any POST request. Without cryptographic verification, an attacker can spoof payloads to trigger unauthorized actions like CI/CD deployments, database wipes, or privilege escalation. To secure these, you must implement HMAC signature verification using a shared secret and constant-time comparison to prevent timing attacks.
The Vulnerable Pattern
package controllersimport ( “encoding/json” “github.com/beego/beego/v2/server/web” )
type WebhookController struct { web.Controller }
// @router /webhook [post] func (c *WebhookController) Post() { // VULNERABILITY: No signature verification. // Anyone can POST malicious data to this endpoint. var payload map[string]interface{} json.Unmarshal(c.Ctx.Input.RequestBody, &payload)
processAction(payload["action"]) c.Ctx.WriteString("Success")
}
The Secure Implementation
The secure implementation introduces a shared secret known only to the sender and the Beego application. We compute an HMAC-SHA256 hash of the raw request body and compare it to the signature provided in the request header. Crucially, we use 'subtle.ConstantTimeCompare' to mitigate timing attacks, where an attacker could otherwise deduce the correct signature character-by-character based on server response times. Ensure 'copyrequestbody = true' is set in your Beego config to access the raw body.
package controllersimport ( “crypto/hmac” “crypto/sha256” “crypto/subtle” “encoding/hex” “github.com/beego/beego/v2/server/web” “os” )
type WebhookController struct { web.Controller }
func (c *WebhookController) Post() { secret := []byte(os.Getenv(“WEBHOOK_SECRET”)) signature := c.Ctx.Input.Header(“X-Hub-Signature-256”) requestBody := c.Ctx.Input.RequestBody
if signature == "" { c.CustomAbort(401, "Missing signature") } mac := hmac.New(sha256.New, secret) mac.Write(requestBody) expectedMAC := "sha256=" + hex.EncodeToString(mac.Sum(nil)) // Use ConstantTimeCompare to prevent timing side-channel attacks if subtle.ConstantTimeCompare([]byte(signature), []byte(expectedMAC)) != 1 { c.CustomAbort(403, "Invalid signature") } // If verified, proceed to process the payload processAction(requestBody) c.Ctx.WriteString("Verified")
}
Your Beego API
might be exposed to Insecure Webhooks
74% of Beego apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.