Webhooks are the connective tissue of modern SaaS ecosystems, used to notify external systems of payment completions, subscription changes, and code commits. Yet both receiving (inbound) and sending (outbound) webhooks introduce severe security vulnerabilities if not engineered with defensive cryptographic controls.
Inbound webhook vulnerabilities: forgery and replay
When your API accepts inbound webhooks from third-party services (like Stripe or GitHub), an attacker can forge HTTP POST requests to trigger unauthorized business actions unless signatures are verified:
- Missing signature verification: trusting incoming webhook payloads without validating HMAC-SHA256 signatures.
- Timing attacks: using standard string comparison (`===`) to check signatures, allowing attackers to reconstruct valid signatures via byte-level timing analysis.
- Replay attacks: accepting valid signed payloads hours or days after original transmission without checking timestamp freshness.
Outbound webhook vulnerabilities: SSRF risks
If your platform allows customers to configure custom outbound webhook URLs, malicious users can specify internal IP addresses (`http://169.254.169.254` or `http://localhost:8080`) to launch internal SSRF attacks against your infrastructure.
Use constant-time comparison functions (such as `crypto.timingSafeEqual`) to verify webhook signatures, enforce strict timestamp tolerance (within 5 minutes), and validate outbound destinations against private IP ranges.