Signature Verification
Verifying the request signature
Each webhook request will include a Slope-Signature
header that may be used to verify the request. The header value takes on the format:
POST https://your-website.com/slope-webhook HTTP/1.1
Slope-Signature: <timestamp>;<algorithm>=<hmac>,<algorithm>=<hmac>
timestamp
is the Unix timestamp at which the request was sent. It is used to generate the signature digests to help prevent replay attacks.algorithm
describes the hash function used to compute the HMAC value.hmac
is the HMAC value that should be compared against.
The request may include a comma-separate list of algorithm-HMAC pairs (<algorithm>=<hmac>
) in the event of multiple webhook secret existing for your endpoint configuration (eg; during webhook secret rotation). When multiple pairs exist, you should verify against each.
Building the expected signature
To build the expected signature, here is an example in Javascript:
// 1. Extract the timestamp and actual signature values from the `Slope-Signature` header.
var parts = headers['Slope-Signature'].split(';');
var timestamp = parts[0];
var signatures = parts[1].split(',');
// 2. Format the payload to sign:
var payload = timestamp + '.' + JSON.stringify(request.body);
var expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');
// 3. Generate the expected signature and compare:
let isVerified = false;
for (var signature of signatures) {
if (signature.split('=')[1] === expected) {
isVerified = true
break;
}
}
return isVerified;
Stale timestamps
To protect against replay attacks, you should also ensure the signature's timestamp is not too old. We recommend no older than 5 minutes but the threshold is up to you.
Updated 5 months ago