From 47ff8bd8c010ad94a0a762813d45f61c91e32b73 Mon Sep 17 00:00:00 2001 From: Jamie Patel Date: Thu, 30 Apr 2015 11:39:27 +0100 Subject: [PATCH] Webhook validation uses hmac.Equals instead of unsafe == --- client.go | 2 +- crypto.go | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/client.go b/client.go index d276c4d..481cbc8 100644 --- a/client.go +++ b/client.go @@ -395,7 +395,7 @@ If it is invalid, the first return value will be nil, and an error will be passe func (c *Client) Webhook(header http.Header, body []byte) (*Webhook, error) { for _, token := range header["X-Pusher-Key"] { - if token == c.Key && checkSignature(header.Get("X-Pusher-Signature"), string(body), c.Secret) { + if token == c.Key && checkSignature(header.Get("X-Pusher-Signature"), c.Secret, body) { return unmarshalledWebhook(body) } } diff --git a/crypto.go b/crypto.go index a87e96e..91b0f6d 100644 --- a/crypto.go +++ b/crypto.go @@ -5,18 +5,28 @@ import ( "crypto/md5" "crypto/sha256" "encoding/hex" + // "fmt" "strings" ) func hmacSignature(toSign, secret string) string { - _authSignature := hmac.New(sha256.New, []byte(secret)) - _authSignature.Write([]byte(toSign)) - return hex.EncodeToString(_authSignature.Sum(nil)) + return hex.EncodeToString(hmacBytes([]byte(toSign), []byte(secret))) } -func checkSignature(result, body, secret string) bool { - expected := hmacSignature(body, secret) - return result == expected +func hmacBytes(toSign, secret []byte) []byte { + _authSignature := hmac.New(sha256.New, secret) + _authSignature.Write(toSign) + return _authSignature.Sum(nil) +} + +func checkSignature(result, secret string, body []byte) bool { + expected := hmacBytes(body, []byte(secret)) + resultBytes, err := hex.DecodeString(result) + + if err != nil { + return false + } + return hmac.Equal(expected, resultBytes) } func createAuthMap(key, secret, stringToSign string) map[string]string {