Why Secure Your Webhooks?
Webhooks are a powerful way to receive real‑time data from external services. However, without proper security measures they can become a vector for attacks such as replay attacks, data tampering, and unauthorized data access.
Best Practices
- Use Secret Signatures – Require the sender to sign each payload with a shared secret (HMAC SHA‑256) and verify it on receipt.
- Validate Payload Structure – Use JSON schema validation to ensure only expected fields are processed.
- Enforce HTTPS – Always expose webhook endpoints over TLS to protect data in transit.
- Rate Limiting & IP Whitelisting – Limit calls per minute and restrict requests to known IP ranges when possible.
- Replay Protection – Include timestamps and nonces; reject messages older than a short window (e.g., 5 minutes).
- Minimal Permissions – Design the endpoint to only accept what it needs; avoid exposing extra data.
Sample Verification Code (Node.js)
const crypto = require('crypto');
function verifySignature(req, secret) {
const signature = req.headers['x-signature'] || '';
const payload = JSON.stringify(req.body);
const hmac = crypto.createHmac('sha256', secret);
const expected = 'sha256=' + hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
// Express middleware
app.post('/webhook', express.json(), (req, res) => {
const secret = process.env.WEBHOOK_SECRET;
if (!verifySignature(req, secret)) {
return res.status(401).send('Invalid signature');
}
// Process payload...
res.status(200).send('OK');
});
Testing Your Endpoint
Use curl or a tool like Postman to simulate webhook calls. Ensure you include the required signature header.
curl -X POST https://example.com/webhook \
-H "Content-Type: application/json" \
-H "X-Signature: sha256=YOUR_SIGNATURE" \
-d '{"event":"order.created","data":{"id":123}}'