This guide outlines how to verify the authenticity of webhook requests sent from Ninjahire’s platform to your systems. Webhook requests include a cryptographic signature to ensure the integrity and authenticity of the data received. By verifying the signature, you can be confident that the data has not been tampered with and originates from Ninjahire.
Each webhook request from Ninjahire includes:
X-NINJAHIRE-Signature
) and a timestamp (X-NINJAHIRE-Timestamp
).The cryptographic signature allows you to verify that the payload has not been altered and that the request was made by Ninjahire. You will use a shared secret key (provided by Ninjahire) to recreate the signature and compare it to the one sent with the request.
When Ninjahire sends a webhook, the following headers are included:
X-NINJAHIRE-Signature
: A cryptographic HMAC SHA-256 signature of the payload.X-NINJAHIRE-Timestamp
: The Unix timestamp indicating when the request was made.You will use the X-NINJAHIRE-Signature
header to verify the payload's integrity.
To verify that the request is authentic:
Extract the Signature and Timestamp:
X-NINJAHIRE-Signature
and X-NINJAHIRE-Timestamp
from the webhook headers.Recreate the Signature:
Compare Signatures:
Ensure the Request is Fresh:
X-NINJAHIRE-Timestamp
to prevent replay attacks. Requests that are too old should be rejected.Below is an example in JavaScript/Node.js for verifying the webhook signature:
const crypto = require('crypto');
// Shared secret key provided by Ninjahire
const secretKey = 'YOUR_SHARED_SECRET';
// Function to verify the signature
function verifySignature(receivedSignature, payload, timestamp) {
// Create the HMAC SHA-256 signature
const expectedSignature = crypto
.createHmac('sha256', secretKey)
.update(JSON.stringify(payload))
.digest('hex');
// Timing-safe comparison to prevent timing attacks
const signaturesMatch = crypto.timingSafeEqual(
Buffer.from(receivedSignature),
Buffer.from(expectedSignature)
);
// Check if the request is fresh (within 5 minutes)
const requestAge = Date.now() - parseInt(timestamp, 10);
const isRecent = requestAge < 5 * 60 * 1000; // 5 minutes in milliseconds
return signaturesMatch && isRecent;
}
// Example usage
const payload = {/* the data sent in the webhook */};
const receivedSignature = 'SIGNATURE_FROM_HEADER';
const timestamp = 'TIMESTAMP_FROM_HEADER';
if (verifySignature(receivedSignature, payload, timestamp)) {
console.log('Signature verified. Webhook is valid.');
} else {
console.log('Signature verification failed. Webhook may be tampered with.');
}
crypto.createHmac()
method with the shared secret and the payload.crypto.timingSafeEqual()
to safely compare the received and expected signatures.X-NINJAHIRE-Timestamp
) is recent to avoid replay attacks.Validate Timestamp: Always check the X-NINJAHIRE-Timestamp
to ensure the request is recent. Reject requests older than a specified window (e.g., 5 minutes) to prevent replay attacks.
HTTPS: Ensure that your webhook endpoint uses HTTPS to encrypt the data in transit, adding another layer of security.
IP Whitelisting: Consider whitelisting Ninjahire’s IP addresses to further secure your webhook endpoint.
Logging: Log all webhook requests and responses for audit and debugging purposes. Ensure you store signature details to help identify potential security issues.
Webhook signature verification is a critical step in ensuring that the data sent to your system is secure and authentic. By implementing the provided steps and using the shared secret key, you can verify that the data has not been altered and the request came from Ninjahire.
If you have any further questions or need additional support, feel free to contact our technical team.