Secure Your Webhooks
Webhook signatures allow you to verify that incoming webhooks are genuinely from Typeform and haven’t been tampered with. This is a critical security measure for production webhooks.
Why verify webhooks?
Without verification, anyone who knows your webhook URL could send fake requests to your endpoint. Signature verification ensures:
- Requests are from Typeform
- Payload hasn’t been modified
- Protection against replay attacks
- Compliance with security best practices
Always verify webhook signatures in production environments. Never trust incoming webhook data without verification.
How webhook signatures work
Typeform includes a signature in the webhook request headers:
- Typeform generates a hash of the request body using HMAC-SHA256
- The hash is created using a secret key (your form’s webhook secret)
- The signature is sent in the
Typeform-Signatureheader - Your server recreates the hash and compares it to the received signature
Getting your webhook secret
When you create or update a webhook, Typeform provides a secret key:
Response:
Store the secret securely in your environment variables. Never commit secrets to version control.
Verifying signatures
Node.js implementation
Python/Flask implementation
Ruby/Sinatra implementation
PHP implementation
Important implementation notes
1. Use raw request body
You must verify the signature against the raw request body string, not a parsed JSON object:
2. Use timing-safe comparison
Always use timing-safe comparison functions to prevent timing attacks:
3. Handle missing signatures
Always check for the presence of the signature header:
Testing signature verification
Create a test webhook
Unit test example
Rotating secrets
Best practice is to rotate webhook secrets periodically:
During rotation, implement a grace period:
Security best practices
- Always verify signatures: Never skip verification in production
- Use HTTPS: Webhooks require HTTPS endpoints
- Store secrets securely: Use environment variables or secret managers
- Rotate secrets regularly: Change secrets periodically
- Log verification failures: Monitor for potential attacks
- Rate limit your endpoint: Prevent abuse
- Validate payload structure: Check that the payload is well-formed
- Use timing-safe comparisons: Prevent timing attacks
Troubleshooting
Signature verification always fails
- Check you’re using the raw body: Don’t verify against parsed JSON
- Verify the secret: Ensure you’re using the correct secret
- Check character encoding: Use UTF-8 encoding
- Inspect the header name: Should be
Typeform-Signature(case-sensitive) - Check signature format: Should be
sha256=<hex_string>
Debugging signatures
Next steps
- Learn about webhook implementation
- See webhook payload examples
- Review the API Reference for webhook endpoints