Myth - Static IPs completely solves webhooks security
A common myth we have heard from multiple people when talking about webhook security is that whitelisting static IPs at the receivers’ end is an enough security measure.
In this guide, we discuss why it isn’t enough and how can things go wrong. When discussing any security issue, it’s essential to put the black-hat cap and try to exploit the system which relies only on static IPs.
The simplest way in which this can blow up is that if by chance the static IPs are rotated or released to the cloud providers pool but the receiver hasn’t updated the whitelist on their end. But there are other ways as well.
Let’s say I am attacker trying to compromise your systems. I will probably start by figuring out all the public IPs belonging to you. Most of the times, this is easy, as some of them will be listed on the webhook sender’s website (so that receivers can whitelist them). Some of them may not be listed (like IP addresses of bastion instances, etc), which can also be found by first doing a DNS lookup of all domains belonging to the sender, and maybe compromising the link between an employee and their internet provider (if the resident/office building has lax security guards, I can install a malicious router pretending to be your internet provider and conduct a man-in-the-middle attack), and many more ways.
Now that I have the list of IPs, the first thing to do is check all open ports and figure out what applications are being run on those ports. Bonus if I can figure out which version of the software is being run. My first course of action will be to gain access to a small portion of the network without the intrusion being detected and the weakest links would be the VMs/instances with public IPs.
If the VM/instance I got access to has a public IP attached which is the whitelisted IP for webhooks, voila, I can now start sending malicious requests to your receivers and they would believe they are receiving correct webhooks and would start processing them.
More likely than not, I still have to do a bit more work before the exploit begins. Through the bastion instance, I can maybe get access to a an instance in a private subnet which has a NAT gateway for outgoing connections. Checking whether the NAT gateway’s IP is in the whitelist is easy, all I have to do is send a cURL request to a system which shows me the IP. I may have to roam around your network until I get access to an instance which uses the whitelisted IPs for outgoing network connections.
Now if that happens, I may not have gained access to the core system which is responsible for sending webhooks. But since most architectures reuse NAT gateways for multiple services, I can still begin the exploit without having gained access to the webhooks service. Of course, a properly segmented network with good ACLs can delay the attack since it will be more difficult for me to get into a private subnet from a instance with public IP but it can’t completely prevent me.
So, how is implementing HMAC signature along with static IPs a good idea?
It increases the time the intruder has to spend to get into the webhook service which helps in intrusion detection. The intruder has to gain access to the webhook service and also gain the secret for the particular endpoint before they are start attacking and sending malicious webhooks. This way you make the intruder jump through more hoops. Maybe they start evaluating whether the effort is worth it before they give up? Maybe the intrusion detection systems can now detect and block since they have gotten enough time? It still buys you more time.
Note: Nothing in cyber security is a full proof solution. Having static IPs and HMAC is no excuse for not having good intrusion detection, network segmentation, reducing surface area for attacks, etc.