mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-28 15:27:03 +02:00
52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
import { createHash } from 'crypto';
|
|
import jwt from 'jsonwebtoken';
|
|
import type { IDataObject, IWebhookFunctions } from 'n8n-workflow';
|
|
|
|
import { verifySignature as verifySignatureGeneric } from '../../utils/webhook-signature-verification';
|
|
|
|
/**
|
|
* Verifies the Netlify webhook signature.
|
|
*
|
|
* Netlify signs webhooks using a JSON Web Signature (HS256):
|
|
* 1. The `X-Webhook-Signature` header carries a JWT signed with the shared
|
|
* secret.
|
|
* 2. The JWT payload includes a `sha256` claim — the hex SHA-256 digest of
|
|
* the raw request body.
|
|
* 3. Verifying the JWT confirms authenticity; comparing the `sha256` claim
|
|
* with the computed digest of the body confirms payload integrity.
|
|
*
|
|
* @returns true if the signature is valid, false otherwise
|
|
* @returns true if no secret is configured (backward compatibility with old triggers)
|
|
*/
|
|
export function verifySignature(this: IWebhookFunctions): boolean {
|
|
const req = this.getRequestObject();
|
|
const webhookData = this.getWorkflowStaticData('node');
|
|
const secret = webhookData.webhookSecret;
|
|
|
|
return verifySignatureGeneric({
|
|
getExpectedSignature: () => {
|
|
if (!secret || typeof secret !== 'string' || !req.rawBody) {
|
|
return null;
|
|
}
|
|
const payload = Buffer.isBuffer(req.rawBody) ? req.rawBody : Buffer.from(req.rawBody);
|
|
return createHash('sha256').update(payload).digest('hex');
|
|
},
|
|
skipIfNoExpectedSignature: !secret || typeof secret !== 'string',
|
|
getActualSignature: () => {
|
|
const token = req.header('x-webhook-signature');
|
|
if (typeof token !== 'string' || !token || typeof secret !== 'string') {
|
|
return null;
|
|
}
|
|
try {
|
|
const decoded = jwt.verify(token, secret, {
|
|
algorithms: ['HS256'],
|
|
issuer: 'netlify',
|
|
}) as IDataObject;
|
|
return typeof decoded.sha256 === 'string' ? decoded.sha256 : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
},
|
|
});
|
|
}
|