11

I am building a Ruby on Rails API that posts to webhooks that the API user can create, whenever a resource that he manages is created, updated or destroyed, using the HTTParty gem. This got me thinking: I am validating that the webhook url is indeed a valid url, but that's it.

What if, for example, the API posts to a webhook that redirects forever? Or, maybe even worse, a webhook that in turn communicates with the API again, triggering more webhooks, so that eventually the API has to handle an infinite amount of webhooks?

These are just two examples, but I guess a lot more could happen.

The one thing I have come up with is to put all posts to webhooks in background tasks, so that at least the workload is distributed to workers, in case someone tries a DOS attack (but then again, I am not sure if that properly protects me from DOS attacks).

Are there any other common threats/pitfalls when using webhooks? What can I do to defend against harmful webhooks and how can I detect them?

  • 3
    I'm surprised nobody here has mentioned the possibility of the user inputting the internal address of a server in your network, that would normally be firewalled off from the public, in order to trigger POSTs to it. – Mark Amery Feb 9 '16 at 16:33
5

In addition to "validating webhook URLs", implement rate limiting on your API endpoints and/or calling webhooks.

If you have a big/popular enough service you should have this even if you don't allow users to have custom callback URLs — eventually somebody will attempt to make a million requests against a resource-intensive (for you) API endpoint, and you really should have protection in place.

That is — you don't have to thoroughly try to detect "malicious" URLs — just have logic in place that would cut off access if a single account makes X requests within Y minutes (add more complex logic as needed).

——

Of course you should also:

  • run webhooks asynchronously (in the background) so your API speed does not depend on a 3rd party.
  • run basic checks that prevent infinite redirect loops, and (for example) blacklist your own domain (make sure to check the blacklist for each redirect target separetely).
  • Yeah, I have a throttle in place. I guess I will take a look if there is a way to tell HTTParty not to follow redirects and also implement a blacklist for webhook urls. Thank you! – weltschmerz Dec 24 '13 at 0:42
4

These concerns are all very valid and we've had to consider them when writing the PubSubHubbub spec. We 'solved' most of them by having a verification step which involves executing the webhook and expecting a specific answer from it. Basically when a new hook is added, it's called with a GET request and an additional 'hub.challenge' param. The webhook then MUST respond with a 200 and echo the hub.challenge in the body.

Generally, I would recommand looking at PubSubHubbub when implementing a webhooks "API", because that's what it is :) Initially it was designed for RSS/Atom but now works with any type of resources, including JSON. It also provides mechanisms for secure delivery (using secret and HMAC signatures).

3

Bringing this down from comment because it's important.

A concern to address as well is internal targets. For example, an attacker could pass an address that is internal to your network that would normally be firewalled off and/or hidden behind NAT. The implications of this vary wildly based on your application.

Consider also the possibility of accessing infrastructure resources like AWS S3 buckets, Dynamo DB databases, or SQS queues. Depending on your configuration, you could be allowing arbitrary writes to these resources. Depending on your setup, it may be possible for an attacker to read/write data to/from one of these services, and then have that data exfiltrated via regenerative webhook (trigger another webhook that would echo this data) back to his/her own server!

This is something to consider when validating webhook URLs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.