Webhook Security Keys
To improve the security of your Webhook integration you can verify the sent signature on each call to your server to ensure that requests came from to.co.
Find your Security Key
When you configured the Webhook it was automatically allocated a Security Key. You can view the Security Key on the Webhooks page in to.co.
Verify the Signature
All outgoing requests carry a hash-based authentication code computed using the standard SHA256 hash function in an X-TOCO-Signature header.
To verify the signature on your receiving server simply generate a SHA256 hash and compare it with the hash sent in the X-TOCO-Signature header.
The hash sent is created from a concatenation of the following string values:
- X-TOCO-Timestamp header value which is the time the Webhook was called in UNIX Epoch format.
- : colon character.
- JSON request body.
Request headers with Signature and Timestamp headers
POST /yourWebhookServer/push HTTP/1.1
Content-Type: application/json;
Content-encoding: gzip
X-TOCO-Timestamp: 1536947409
X-TOCO-Signature: 68688b9dbd5c381851d3cd51dba3093c6633ceef58e6fee6ad4757f857f59aea
Example Signature Validation code - NodeJS
function isValidSignature(request) {
var key = "secret key provided by to.co on the Webhook setup page";
var headers = request.headers;
// Note that NodeJS http requires using lowercase for all headers
var signature = headers["x-toco-signature"];
var body = ""; // Create an empty variable for the Body
// If request body isn't empty, assign value to variable
if (request.body) {
body = request.body;
}
var message = headers["x-toco-timestamp"] + ":" + body; // Concatenation of received timestamp and body
var hmac = crypto.createHmac("sha256", key); // Create a sha256 hashed code using the secret key
hmac.update(message, "utf8"); // Update the hash with the concatenated message using utf8
var digest = hmac.digest("hex");
return signature === digest; // If signature equals your hashed code, return true
}
Recommendations
To prevent replay attacks, you should validate the X-TOCO-Timestamp within a threshold of the current time. We recommend that you use a 5-minute threshold to account for time drift. To prevent timing attacks, you should employ a constant time-compare function when checking signatures.