Collection of best practices for providing and consuming webhooks
There are some interesting attack vectors to be aware of if you run a service where users can define webhooks, and your service will will call the user-defined webhooks to notify about certain system events. In my case, a monitoring service which can send notifications by calling user-defined webhook.<p>* Timeouts: the user can set up a webhook receiver that takes very long to generate a response. Your service must be able to deal with that.<p>* Timeouts (slowloris): the webhook target could be sending back one byte at a time, with 1 second pauses inbetween. If you are using, say, the "requests" python library for making HTTP requests, the "timeout" parameter will not help here<p>* Private IPs and reserved IPs: you probably don't want users defining webhooks to <a href="http://127.0.0.1:<some-port>" rel="nofollow">http://127.0.0.1:<some-port></a> and probing your internal network. Remember about private IPv6 ranges too<p>* Domains that resolve to private IPs: attacker could set up foo.com which resolves to a private IP. It is not enough to just validate webhook URLs when users set them up.<p>* HTTP redirects to private IPs. If your HTTP client library follows HTTP redirects, the attacker can set up a webhook endpoint that redirects to a private IP. Again, it is not enough to validate the user-supplied URL.<p>* Excessive HTTP redirects. The attacker can set up a redirect loop - make sure this does not circumvent your timeout setting.<p>My current solution for all of the above is to use libcurl via pycurl. I wrote a wrapper that mimics requests API: <a href="https://github.com/healthchecks/healthchecks/blob/master/hc/lib/curl.py" rel="nofollow">https://github.com/healthchecks/healthchecks/blob/master/hc/...</a> (may contain bugs, use at your own risk :-)