Security
Webhook Security
Securing your webhook endpoints is crucial to ensure that only legitimate requests from ContactManager are processed by your application. This guide explains how ContactManager secures webhooks and how to verify webhook signatures.
How Webhook Signing Works
-
ContactManager generates a unique webhook secret for each webhook endpoint
-
When an event occurs, we:
- Create a timestamp
- Prepare the event payload
- Combine the timestamp and payload
- Sign the combined data with your webhook secret using HMAC-SHA256
- Send the request with the signature in the
X-Webhook-Signature
header
-
Your server:
- Extracts the timestamp and signature from the header
- Uses the same process to compute the expected signature
- Compares the signatures to verify authenticity
Signature Format
The X-Webhook-Signature
header uses this format:
Where:
t=1672531200
is the Unix timestamp when the request was createdv1=5257a86...
is the signature (64-character hex string)
Verifying Signatures
Using Our SDKs
The easiest way to verify signatures is to use our SDKs:
Python
Node.js
Manual Verification
If you’re not using our SDKs, here’s how to verify signatures:
- Extract the timestamp (
t
) and signature (v1
) components from the header - Verify the timestamp is recent (within 5-15 minutes) to prevent replay attacks
- Compute the expected signature using HMAC-SHA256:
- Create the string
{timestamp}.{request_body}
- Sign it with your webhook secret
- Compare with the received signature using a constant-time comparison function
- Create the string
Security Best Practices
-
Store your webhook secret securely
- Use environment variables or a secure key management system
- Never hard-code your webhook secret in your codebase
- Don’t log your webhook secret
-
Use HTTPS for your webhook endpoint
- Ensures data is encrypted in transit
-
Implement IP allowlisting
- Restrict access to your webhook endpoint to ContactManager’s IP ranges
- We’ll provide our IP ranges in the dashboard
-
Verify every webhook signature
- Never skip signature verification, even in development
- Process webhooks only after verification
-
Use constant-time comparison
- Use specialized functions that prevent timing attacks
- Examples:
hmac.compare_digest()
in Python,crypto.timingSafeEqual()
in Node.js
-
Implement rate limiting
- Protect against denial of service attacks
- Return 429 responses when limits are exceeded
Rotating Webhook Secrets
You can rotate your webhook secret at any time without downtime:
- Generate a new webhook secret in the dashboard
- Update your application to accept both the old and new secrets
- Verify each webhook against both secrets, accepting if either matches
- Once all systems are updated, remove the old secret
How We Secure Your Webhooks
ContactManager implements several security measures to protect your webhook system:
- Secure Secret Generation: Webhook secrets are generated using cryptographically secure random generators
- Secret Storage: Webhook secrets are never stored in plaintext - we use a secure vault system with encryption at rest
- HTTPS Only: All webhook requests are sent over HTTPS
- Request Signing: Every webhook request is signed with your unique webhook secret
- Timestamp Verification: Signatures include timestamps to prevent replay attacks
- Delivery Logs: All webhook delivery attempts are logged for audit and debugging
Testing Signature Verification
You can test your signature verification implementation using the test tool in your dashboard. This allows you to:
- Send test events to your endpoint
- Verify that your signature validation works correctly
- Debug any implementation issues
For more advanced topics, see our webhook implementation guide.