How to verify a post-receive hook request actually came from github?
Asked Answered
B

5

16

Github offers a way to let a URL know when a project has been updated using webhooks.

How do I verify that a post sent to my server's post-receive hook actually came from github?

Should I check the IP address of the sender or can I send an auth check somewhere? I want to make sure someone doesn't try to spoof a request pretending to be from github.

One option is to setup the hook through PubSubHubbub and use the hub.secret option to create a SHA1 HMAC signature of the post body. However, that would require my server setting up the request rather than waiting for users to setup the post-receive callback to my site when they want to. I would rather just ask users to paste the URL I give them into the post url.

Blackbeard answered 25/1, 2012 at 17:18 Comment(0)
T
7

You can try to check Github's post-request IP : 207.97.227.253, 50.57.128.197, 108.171.174.178

Tyne answered 21/2, 2012 at 17:55 Comment(7)
So simple I didn't even consider it. The data is not super important, I just want to stop simple spam submissions.Blackbeard
According to Github, the actual addresses are 207.97.227.253, 50.57.128.197, 108.171.174.178.Bail
This sounds fragile. If github ever changes those IP addresses, you'll have to update your list. Perhaps you can do a reverse DNS lookup and ensure that the resulting domain name ends with "github.com".Lachman
@Joshua, can you please provide the source for that IP address information? I'm having trouble finding any information on github.com. Thanks!Warrantable
I've seen those IPs too. Go to the Admin/Settings part of a repo, click Service Hooks, then click WebHook URLs. You'll see a message on the right: "The Public IP addresses for these hooks are: 207.97.227.253, 50.57.128.197, 108.171.174.178."Digastric
Don't use the above addresses, go get the current ones (a CIDR Range) as described in the comment by @RichDoughertySeedy
Don't look up IPs. Github has specific recommendations on verifying requests... see @Rowan's answer.Baptlsta
L
10

You can ping GitHub's Meta API to get an array of IP addresses (in CIDR notation) that the incoming service hooks will originate from and cross check them against the request's IP :

https://api.github.com/meta

Larrisa answered 20/8, 2013 at 21:50 Comment(0)
C
9

Take a look at GitHub's docs on the subject: they suggest using HTTPS and basic authentication.

Specifically, set up your Payload URL in this format:

https://yourUser:[email protected]/path

If you have a number of users, you'd give each a different username & password. Assuming they keep that password private, you can then trust that an authenticating request really does come from GitHub and from that account.

See also: https://github.com/blog/237-basic-auth-post-receives

Cogitable answered 31/12, 2013 at 11:51 Comment(0)
T
7

You can try to check Github's post-request IP : 207.97.227.253, 50.57.128.197, 108.171.174.178

Tyne answered 21/2, 2012 at 17:55 Comment(7)
So simple I didn't even consider it. The data is not super important, I just want to stop simple spam submissions.Blackbeard
According to Github, the actual addresses are 207.97.227.253, 50.57.128.197, 108.171.174.178.Bail
This sounds fragile. If github ever changes those IP addresses, you'll have to update your list. Perhaps you can do a reverse DNS lookup and ensure that the resulting domain name ends with "github.com".Lachman
@Joshua, can you please provide the source for that IP address information? I'm having trouble finding any information on github.com. Thanks!Warrantable
I've seen those IPs too. Go to the Admin/Settings part of a repo, click Service Hooks, then click WebHook URLs. You'll see a message on the right: "The Public IP addresses for these hooks are: 207.97.227.253, 50.57.128.197, 108.171.174.178."Digastric
Don't use the above addresses, go get the current ones (a CIDR Range) as described in the comment by @RichDoughertySeedy
Don't look up IPs. Github has specific recommendations on verifying requests... see @Rowan's answer.Baptlsta
B
5

In addition to @mnml's answer, the second step could be to just call up the API and verify that the information given matches the last known commit for the project. It's the same process that OpenID uses to verify the data passed is valid.

So, first I could defeat dumb reply attacks, by just checking the IP. Next I could ask github if the information I received is correct.

GET /repos/:user/:repo/commits/:sha
Blackbeard answered 21/2, 2012 at 18:31 Comment(2)
Yep I also use the json data to trigger capistrano and deploy depending on the branch of the commitTyne
This is not safe – everybody can add commits to your repo by creating pull requests. See here: api.github.com/repos/github/gitignore/git/commits/…. Part of this (not merged!) pull request: github.com/github/gitignore/pull/542.Halfpenny
A
3

You could locate your webhook at a hard-to-guess URL. Say:

https://my-host.com/webhooks/E36006BE2C4BABDEEF307C77E34F415B/my-hook

(That's 128-bits of random data - increase to whatever size feels comfortable). Assuming you can trust github to keep this url secure, it's pretty likely that a client hitting that url can be trusted.

If the url should ever be compromised, it's a simple matter to just generate a new random URL and update your webserver.

Just make sure you're using a good source of entropy...

Aramen answered 2/3, 2012 at 15:47 Comment(4)
Yeah but then if you have a lot of web hooks you'd have to update them all with the new URL if your URL ever became compromised.Neral
Isn't the URL clear-text once it is used and sent over the internet?Vivien
The request path is encrypted when sent via HTTPS.Digastric
It's funny that this got much less upvotes than the HTTP auth answer even though they are practically the same thing.Risorgimento

© 2022 - 2024 — McMap. All rights reserved.