Skip to content

ValidatePayload does not correctly parse mime type from Content-Type header #1874

@shmyer

Description

@shmyer

When validating webhook payloads the Content-Type header is compared in a switch statement with either application/json or application/x-www-form-urlencoded

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions