Template Docs Commerce APIs Webhooks Tools
Get Started
Get Started

Verifying notifications

Because webhook endpoints are accessible to the public, they're prone to malicious attacks. That's why it's a best practice to verify webhook notifications to determine if they're from Squarespace.

Structure of a Squarespace notification

Read the Webhook overview to see how a Squarepsace notification is structured.

1. Retrieve the webhook subscription's secret from its secure location

Every Squarespace notification includes a Squarespace-Signature header. To verify this header, you must have access to the secret from the appropriate Webhook Subscription.

A secret is only returned when creating a subscription or rotating a secret, and is always a hexadecimal value.

2. Generate the expected Squarespace-Signature

Squarespace generates the Squarespace-Signature header using HMAC with SHA-256. Compute the expected signature by signing the payload with the secret from the Webhook Subscription as the key:

Expected signature = HMAC-SHA256(hexToBytes(secret), request payload)

Note: The hex-encoded secret should be decoded to raw bytes when constructing the HMAC otherwise the expected signature won't match. The request payload is the raw HTTP request body as a UTF-8 string without any formatting applied.

3. Compare the signatures

Compare the expected signature with the Squarespace-Signature header in the notification. If the signatures match, then the notification was sent from Squarespace.

Note: Use a constant-time comparison function when checking if two signatures match to protect against timing attacks.

Examples

Node

const crypto = require('crypto');

const expectedSignature = crypto.createHmac('sha256', Buffer.from(secret, 'hex'))
  .update(payload)
  .digest('hex');

const isFromSquarespace = crypto.timingSafeEqual(Buffer.from(expectedSignature), Buffer.from(headerSignature))

OpenSSL

echo -n $PAYLOAD | openssl sha256 -mac hmac -macopt hexkey:$SECRET