-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Closed
Closed
Copy link
Labels
Description
When validating webhook payloads the Content-Type
header is compared in a switch statement with either application/json
or application/x-www-form-urlencoded
Lines 157 to 206 in 0318e77
func ValidatePayload(r *http.Request, secretToken []byte) (payload []byte, err error) { | |
var body []byte // Raw body that GitHub uses to calculate the signature. | |
switch ct := r.Header.Get("Content-Type"); ct { | |
case "application/json": | |
var err error | |
if body, err = ioutil.ReadAll(r.Body); err != nil { | |
return nil, err | |
} | |
// If the content type is application/json, | |
// the JSON payload is just the original body. | |
payload = body | |
case "application/x-www-form-urlencoded": | |
// payloadFormParam is the name of the form parameter that the JSON payload | |
// will be in if a webhook has its content type set to application/x-www-form-urlencoded. | |
const payloadFormParam = "payload" | |
var err error | |
if body, err = ioutil.ReadAll(r.Body); err != nil { | |
return nil, err | |
} | |
// If the content type is application/x-www-form-urlencoded, | |
// the JSON payload will be under the "payload" form param. | |
form, err := url.ParseQuery(string(body)) | |
if err != nil { | |
return nil, err | |
} | |
payload = []byte(form.Get(payloadFormParam)) | |
default: | |
return nil, fmt.Errorf("Webhook request has unsupported Content-Type %q", ct) | |
} | |
// Only validate the signature if a secret token exists. This is intended for | |
// local development only and all webhooks should ideally set up a secret token. | |
if len(secretToken) > 0 { | |
sig := r.Header.Get(sha256SignatureHeader) | |
if sig == "" { | |
sig = r.Header.Get(sha1SignatureHeader) | |
} | |
if err := ValidateSignature(sig, body, secretToken); err != nil { | |
return nil, err | |
} | |
} | |
return payload, nil | |
} |
This is not working for Content-Type headers which contain for example a charset, resulting in those webhooks being rejected:
Content-Type: application/json; charset=UTF-8
The correct way to validate the mime type might look something like this:
https://gist.github.com/rjz/fe283b02cbaa50c5991e1ba921adf7c9