Skip to main content

Overview

Securing your webhook endpoints is critical to ensure that webhook requests are coming from Gu1 and not from malicious actors. This guide covers how to verify webhook signatures, implement security best practices, and avoid common security mistakes.

Signature Verification

Gu1 signs all webhook requests with an HMAC SHA-256 signature using your webhook secret. The signature is sent in the X-Webhook-Signature header, allowing you to verify that the request is authentic.

How Signature Verification Works

  1. Gu1 generates a signature: When sending a webhook, Gu1 creates an HMAC SHA-256 hash of the raw request body using your webhook secret
  2. Signature is sent in header: The signature is included in the X-Webhook-Signature header
  3. Your server recalculates: Your endpoint recalculates the signature using the same secret and raw body
  4. Compare signatures: If the signatures match, the webhook is authentic
Always verify webhook signatures in production. Without verification, anyone can send fake webhooks to your endpoint and potentially compromise your system.

Signature Verification Examples

Node.js (Express)

Node.js
Critical: You must verify the signature using the raw request body before it’s parsed as JSON. If you verify against the parsed JSON body (e.g., JSON.stringify(req.body)), the signature will not match because JSON formatting may differ.

Python (Flask)

Python
Use hmac.compare_digest() instead of == for comparing signatures in Python. This function performs a timing-safe comparison that prevents timing attacks.

Go (Gin)

Go

Raw Body vs Parsed JSON

A common mistake is to verify the signature using the parsed JSON object instead of the raw request body. This will always fail because JSON formatting can differ.

What Gu1 signs (and what it does not)

Gu1 computes HMAC-SHA256(secret, raw_request_body) and sends the hex digest in X-Webhook-Signature.
Use a timing-safe comparison when checking the signature (for example crypto.timingSafeEqual in Node.js). See the security best practices section below.

Webhook history in the dashboard

The Webhook Monitor shows the payload for debugging and support. That view is not the exact byte string that was signed at delivery time. Pretty-printing, copying from the UI, or running JSON.stringify() on a parsed object can produce a different string and make a correct delivery look invalid. To debug a failed delivery, compare the X-Webhook-Signature header your endpoint received with an HMAC computed over the raw body of that same HTTP request. Do not re-verify from the dashboard JSON alone.

Intermittent signature failures

If verification works for some events but returns 401 Invalid signature for others with the same webhook secret and endpoint, the usual causes are:
  1. Parsed JSON re-stringified β€” JSON.stringify(req.body) after express.json() (or equivalent) does not reliably reproduce Gu1’s body bytes. Different payloads (key order, nested shape, number formatting) can make this fail only sometimes.
  2. Middleware that mutates the body β€” deduplicating arrays, stripping null fields, sorting keys, or normalizing strings before verification changes the signed input.
  3. Wrong secret β€” secret regenerated in the dashboard while an old value remains in your environment.
  4. Missing signature header β€” if the webhook has no secret configured, Gu1 may omit X-Webhook-Signature; treating a missing header as an invalid signature is expected.
Signature verification is optional but recommended. Gu1 still delivers webhooks if you do not verify; a 401 response is returned by your server when your verification logic rejects the request.

Idempotency Patterns

Webhooks may be delivered more than once due to network issues, timeouts, or retries. Implement idempotency to ensure you process each webhook only once.

Database-Based Idempotency

Store processed webhook IDs in your database:
Node.js

Cache-Based Idempotency

For high-volume webhooks, use a cache like Redis:
Node.js with Redis
Python with Redis

Security Best Practices

Never skip signature verification in production environments. This is your primary defense against fake webhooks.
Configure your webhook endpoints to use HTTPS only. Reject HTTP requests:
Only process event types you’re expecting:
Protect your endpoint from abuse with rate limiting:
Never hardcode webhook secrets. Use environment variables or secret management:
For production, use a secret manager:
  • AWS Secrets Manager
  • HashiCorp Vault
  • Azure Key Vault
  • Google Secret Manager
Validate the webhook payload structure before processing:
When comparing signatures, use timing-safe comparison functions to prevent timing attacks:
Log all webhook attempts for auditing and debugging:
Respond with 200 status code quickly to prevent retries. Process heavy work asynchronously:
If webhook processing fails, store it for retry:

Common Security Mistakes to Avoid

Avoid these common security mistakes that can compromise your webhook endpoints:

1. Skipping Signature Verification

Risk: Anyone can send fake webhooks to your endpoint.

2. Verifying Parsed JSON Instead of Raw Body

Risk: Signature verification will always fail.

3. Using HTTP Instead of HTTPS

Risk: Webhook payloads can be intercepted in transit.

4. Hardcoding Secrets

Risk: Secrets exposed in version control or logs.

5. Not Implementing Idempotency

Risk: Duplicate webhooks will create duplicate records.

6. Exposing Errors to Clients

Risk: Internal information leakage to attackers.

7. Not Validating Event Types

Risk: Attackers can send arbitrary event types.

8. Using Weak Secrets

Risk: Secrets can be brute-forced. Solution: Use strong, randomly generated secrets (at least 32 characters).

Testing Webhook Security

Test Invalid Signatures

Test Replay Attacks

Send the same webhook twice and verify idempotency:

Monitoring and Alerting

Set up monitoring for webhook security:

Next Steps

Webhook Configuration

Learn how to configure webhooks

Entity Events

Handle entity lifecycle events

KYC Events

Process KYC verification events

Rule Events

Respond to compliance rules