Skip to contentSkip to navigationSkip to topbar
Page tools
Useful for sharing or LLM
Accelerate development with AI

On this page
Looking for more inspiration?Visit the

Webhook security


Securing your webhook handlers prevents attackers from forging requests, causing duplicate processing, or exploiting your app through webhook endpoints. To notify your app about events, Twilio sends webhook requests. These events include incoming messages, call status changes, or media recordings. Each webhook provides a potential entry point to your system and requires careful protection.


Encrypt data in-flight using TLS

https page anchor

All webhook URLs require secure HTTP with a valid, trusted certificate. Twilio doesn't send webhooks to HTTP endpoints or to endpoints with expired or self-signed certificates unless explicitly configured for development.

Without HTTPS, attackers can intercept webhook requests and steal authentication tokens or sensitive data. HTTPS encrypts the connection and authenticates the server.


Validate webhook signatures

signature page anchor

Twilio signs every webhook request with an included X-Twilio-Signature header. Twilio generates this signature using a hashed value computed with an hash-based message authentication code (HMAC)(link takes you to an external page) and Secure Hash Algorithm 1 (SHA-1)(link takes you to an external page). The hash uses the request URL, request body, and your Auth Token as the secret key.

To validate a webhook signature in your app, follow these steps:

  1. Reconstruct the URL and body matching what Twilio sent.
  2. Compute the HMAC-SHA1 hash using your Auth Token as the secret.
  3. Compare the computed signature to the X-Twilio-Signature header value.
  4. Reject any request with a mismatched or missing signature.

If you don't validate the signatures, your app becomes vulnerable to forged webhooks from an attacker who can predict your webhook URL. Validate signatures as the primary defense against this attack.

Twilio SDKs for popular languages include built-in helper functions for webhook signature validation. These libraries handle URL and body reconstruction, HMAC computation, and comparison. This reduces implementation errors.

(information)

SDK webhook validation utility functions

Twilio recommends using SDK-provided validation helpers.

  • Python: twilio.request_validator.RequestValidator
  • Node.js: twilio.validateRequest()
  • Java: com.twilio.security.RequestValidator
  • C#: Twilio.Security.RequestValidator
  • Ruby: Twilio::Security::RequestValidator
  • PHP: Twilio\Security\RequestValidator
  • Go: client.RequestValidator (from github.com/twilio/twilio-go/client)

Validate payload format and content

payload page anchor

Validate webhook payload format and content after the signatures. To validate a payload, your app should check the following:

  • Required fields have values.
  • Field values match expected types and ranges.
  • Account SID matches your account.
  • Resource SIDs (message IDs, call SIDs, etc.) belong to your account.

Validation prevents malformed requests or requests that target other accounts from processing through your logic.


Handle duplicate webhooks

dupes page anchor

Twilio sends each webhook at least once. Due to retries on failures, Twilio might send duplicates. To implement idempotency checks, store and check processed message IDs or timestamps in a database or cache. When a webhook arrives, check if you've already processed that ID. If so, return success immediately without reprocessing. This prevents duplicate charges, SMS sends, database writes, or notifications to end users.


Respond to webhooks immediately

quick page anchor

Return an HTTP 200 status code(link takes you to an external page) immediately after validating the webhook request. A 200 tells Twilio that your endpoint received the webhook, so Twilio doesn't retry it. Don't wait for downstream processing to complete. Slow responses can time out, and Twilio might treat a timeout as a failure and retry.

To implement this measure:

  1. Validate the webhook signature and payload.
  2. Return an HTTP 200 status code immediately.
  3. Queue long-running tasks asynchronously like sending email, updating database, or calling external API.
  4. Process queued tasks in background workers.

If a webhook handler returns an error status code (non-2xx) or times out, Twilio might retry the webhook, depending on your retry settings. If your handler isn't idempotent, retries can cause duplicate processing.


Harden webhook endpoints

harden-webhook-endpoints page anchor

To harden your webhook endpoints, implement these practices:

  • Use a unique, unpredictable URL for each webhook endpoint. Never use sequential IDs or patterns an attacker could guess.
  • Don't log full webhook request bodies in app logs. Redact or exclude sensitive fields.
  • Limit the rate webhook processing. This detects and mitigates floods of forged or repeated webhooks.
  • Monitor webhook delivery and alert on unusual patterns, such as high failure rates or traffic spikes.
  • Restrict network access to your webhook endpoint using firewalls or API gateways if possible.
  • Validate the source IP if Twilio provides IP allowlisting (where available).

Common webhook security issues

common-webhook-security-issues page anchor
IssueCauseSolution
Webhook signature validation failsURL encoding differences, timestamp parsing, or incorrect secret keyUse Twilio-provided libraries or verify signature validation against Twilio's test vector data. Test with real webhooks in development first.
Duplicate charges or messages from webhook retriesA non-idempotent webhook handler processes the same event twice.Before processing, implement idempotency through storing and checking message IDs. Return HTTP 200 immediately and queue work asynchronously.
Excessive traffic or forged requests to Webhook endpointsPredictable or compromised endpoint URLUse unique, unpredictable URLs. Implement rate limiting and request validation. Monitor for unusual traffic patterns. If compromised, rotate the endpoint URL.

To learn more about webhook and API security, see the following topics: