This article was originally published on AI Study Room. For the full version with working code examples and related articles, visit the original post.
Webhook Security Best Practices
Webhook Security Best Practices
Webhook Security Best Practices
Webhook Security Best Practices
Webhook Security Best Practices
Webhook Security Best Practices
Webhook Security Best Practices
Webhook Security Best Practices
Webhook Security Best Practices
Webhook Security Best Practices
Why Webhook Security Matters
Webhooks are HTTP callbacks that allow services to push real-time events to your application. Unlike APIs where you initiate the request, webhooks are delivered to a public endpoint that anyone with the URL can call. Without proper security, an attacker can replay webhook events, send fake event data, or probe your internal infrastructure.
Threat Model
| Threat | Impact | Likelihood | |--------|--------|------------| | Fake webhook events | Application processes false data | High | | Replay attacks | Duplicate processing of legitimate events | Medium | | Payload tampering | Corrupted data processed as valid | Medium | | Reconnaissance | Attacker probes internal network | Low | | DDoS via webhooks | Service overload from fake events | Medium |
Defense 1: Signature Verification
Every webhook provider signs their payloads. Your endpoint must verify this signature before processing.
Stripe-Style Signatures
import hmac
import hashlib
def verify_stripe_signature(payload, sig_header, secret):
"""Verify Stripe webhook signature."""
Signature format: t=timestamp,v1=signature
parts = dict(item.split('=', 1) for item in sig_header.split(','))
if 'v1' not in parts or 't' not in parts:
return False
timestamp = parts['t']
expected_sig = parts['v1']
Prevent replay: signature must be within 5 minutes
if abs(int(timestamp) - time.time()) > 300:
return False
Compute expected signature
signed_payload = f"{timestamp}.{payload}".encode()
computed_sig = hmac.new(
secret.encode(),
signed_payload,
hashlib.sha256
).hexdigest()
Constant-time comparison
return hmac.compare_digest(computed_sig, expected_sig)
GitHub-Style Signatures
const crypto = require('crypto');
function verifyGitHubSignature(req, secret) {
const signature = req.headers['x-hub-signature-256'];
if (!signature) return false;
const payload = JSON.stringify(req.body);
Read the full article on AI Study Room for complete code examples, comparison tables, and related resources.
Found this useful? Check out more developer guides and tool comparisons on AI Study Room.
Top comments (0)