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

  1. ContactManager generates a unique webhook secret for each webhook endpoint

  2. 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
  3. 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:

t=1672531200,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

Where:

  • t=1672531200 is the Unix timestamp when the request was created
  • v1=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

from contactsmanager import ContactsManagerClient

client = ContactsManagerClient(
    api_key="your_api_key",
    api_secret="your_api_secret",
    org_id="your_org_id"
)
client.set_webhook_secret("your_webhook_secret")

# In your webhook handler
is_valid = client.verify_webhook_signature(request_body, signature_header)

Node.js

const { ContactsManagerClient } = require('@contactsmanager/server');

const client = new ContactsManagerClient({
  apiKey: 'your_api_key',
  apiSecret: 'your_api_secret',
  orgId: 'your_org_id'
});
client.setWebhookSecret('your_webhook_secret');

// In your webhook handler
const isValid = client.verifyWebhookSignature(requestBody, signatureHeader);

Manual Verification

If you’re not using our SDKs, here’s how to verify signatures:

  1. Extract the timestamp (t) and signature (v1) components from the header
  2. Verify the timestamp is recent (within 5-15 minutes) to prevent replay attacks
  3. 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

Security Best Practices

  1. 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
  2. Use HTTPS for your webhook endpoint

    • Ensures data is encrypted in transit
  3. Implement IP allowlisting

    • Restrict access to your webhook endpoint to ContactManager’s IP ranges
    • We’ll provide our IP ranges in the dashboard
  4. Verify every webhook signature

    • Never skip signature verification, even in development
    • Process webhooks only after verification
  5. Use constant-time comparison

    • Use specialized functions that prevent timing attacks
    • Examples: hmac.compare_digest() in Python, crypto.timingSafeEqual() in Node.js
  6. 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:

  1. Generate a new webhook secret in the dashboard
  2. Update your application to accept both the old and new secrets
  3. Verify each webhook against both secrets, accepting if either matches
  4. Once all systems are updated, remove the old secret

How We Secure Your Webhooks

ContactManager implements several security measures to protect your webhook system:

  1. Secure Secret Generation: Webhook secrets are generated using cryptographically secure random generators
  2. Secret Storage: Webhook secrets are never stored in plaintext - we use a secure vault system with encryption at rest
  3. HTTPS Only: All webhook requests are sent over HTTPS
  4. Request Signing: Every webhook request is signed with your unique webhook secret
  5. Timestamp Verification: Signatures include timestamps to prevent replay attacks
  6. 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:

  1. Send test events to your endpoint
  2. Verify that your signature validation works correctly
  3. Debug any implementation issues

For more advanced topics, see our webhook implementation guide.