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.