Template Docs Commerce APIs Webhooks Custom Code Upcoming Changes
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