Webhook Security
Comprehensive guide to securing your webhook integrations against common threats and vulnerabilities.
Signature Verification
Why Verify Signatures
Webhook signatures ensure:
- Authenticity - Request came from the expected source
- Integrity - Data hasn't been tampered with
- Non-repudiation - Source can't deny sending the webhook
Implementation Examples
HMAC SHA-256 (Most Common)
const crypto = require('crypto');
function verifyHMACSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
const receivedSignature = signature.replace('sha256=', '');
return crypto.timingSafeEqual(
Buffer.from(expectedSignature, 'hex'),
Buffer.from(receivedSignature, 'hex')
);
}
HTTPS and Transport Security
TLS Configuration
- Use TLS 1.2 or higher
- Strong cipher suites only
- Valid SSL certificates
- HSTS headers
Certificate Validation
// Validate SSL certificates
const https = require('https');
const agent = new https.Agent({
rejectUnauthorized: true, // Don't accept self-signed certificates
checkServerIdentity: (host, cert) => {
// Additional certificate validation
}
});
Input Validation
Sanitize All Input
const Joi = require('joi');
const webhookSchema = Joi.object({
id: Joi.string().required(),
type: Joi.string().required(),
data: Joi.object().required(),
timestamp: Joi.number().integer().min(0)
});
app.post('/webhooks', (req, res) => {
const { error } = webhookSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: 'Invalid webhook data' });
}
// Process validated webhook
});
Rate Limiting and DDoS Protection
Implement Rate Limiting
const rateLimit = require('express-rate-limit');
const webhookLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 1000, // Limit each IP to 1000 requests per windowMs
message: 'Too many webhook requests'
});
app.use('/webhooks', webhookLimiter);
This section is under development. More security best practices coming soon.