@bernierllc/webhook-validator
v1.0.1
Published
Webhook payload validation with signature verification and schema enforcement
Readme
@bernierllc/webhook-validator
Webhook payload validation with signature verification and schema enforcement.
Installation
npm install @bernierllc/webhook-validatorOverview
Comprehensive webhook validation utilities for verifying signatures, validating payload schemas, and ensuring webhook authenticity. Works with all major webhook providers and custom implementations.
Core Features
- Signature Verification: HMAC-SHA256, JWT, GitHub, Stripe, custom signatures
- Schema Validation: JSON Schema, custom payload validation
- Provider Support: Pre-built validators for GitHub, Stripe, SendGrid, etc.
- Timestamp Validation: Prevent replay attacks with timestamp checking
- Custom Rules: Define domain-specific validation logic
- Security: Timing-safe comparisons, replay protection
Quick Start
Basic Webhook Validation
import { validateWebhook } from '@bernierllc/webhook-validator';
const result = await validateWebhook(
{
headers: request.headers,
body: request.body,
signature: request.headers['x-signature'],
},
{
secret: process.env.WEBHOOK_SECRET,
algorithm: 'hmac-sha256',
timestampTolerance: 300 // 5 minutes
}
);
if (result.valid) {
console.log('Webhook is valid:', result.payload);
} else {
console.error('Validation errors:', result.errors);
}GitHub Webhook Validation
import { validateGitHubWebhook } from '@bernierllc/webhook-validator';
const result = await validateGitHubWebhook(
{
headers: request.headers,
body: request.rawBody,
provider: 'github'
},
process.env.GITHUB_WEBHOOK_SECRET!
);
if (result.valid) {
const event = request.headers['x-github-event'];
console.log(`GitHub ${event} event:`, result.payload);
}Stripe Webhook Validation
import { validateStripeWebhook } from '@bernierllc/webhook-validator';
const result = await validateStripeWebhook(
{
headers: request.headers,
body: request.body,
signature: request.headers['stripe-signature'],
provider: 'stripe'
},
process.env.STRIPE_WEBHOOK_SECRET!
);API Reference
Core Functions
validateWebhook(request, options)
Main validation function that handles generic webhooks and routes to provider-specific validators.
Parameters:
request: WebhookValidationRequest- The webhook request to validateoptions: ValidationOptions- Validation configuration
Returns: Promise<ValidationResult>
validateGitHubWebhook(request, secret)
Validates GitHub webhooks with their specific signature format and headers.
validateStripeWebhook(request, secret)
Validates Stripe webhooks with timestamp-based signatures.
validateSendGridWebhook(request, secret)
Validates SendGrid webhooks with their event format.
Signature Functions
validateHmacSignature(payload, signature, secret, algorithm)
Validates HMAC signatures with timing-safe comparison.
validateJwtSignature(token, secret, options)
Validates JWT tokens with configurable algorithms.
Types
interface WebhookValidationRequest {
headers: Record<string, string>;
body: string | Buffer;
signature?: string;
timestamp?: string;
provider?: 'github' | 'stripe' | 'sendgrid' | 'generic';
}
interface ValidationResult {
valid: boolean;
payload?: any;
errors: ValidationError[];
warnings: ValidationWarning[];
metadata: {
provider?: string;
algorithm?: string;
hasSignature: boolean;
hasTimestamp: boolean;
timestamp?: Date;
processingTime: number;
};
}Custom Validation Rules
import { validateWebhook } from '@bernierllc/webhook-validator';
const result = await validateWebhook(request, {
secret: webhookSecret,
customRules: [
{
name: 'check-api-version',
validator: (payload, headers) => {
const apiVersion = headers['x-api-version'];
return apiVersion === 'v1' || apiVersion === 'v2';
},
message: 'Unsupported API version'
},
{
name: 'validate-event-type',
validator: (payload) => {
const allowedEvents = ['user.created', 'user.updated'];
return allowedEvents.includes(payload.event);
},
message: 'Invalid event type'
}
]
});Security Features
Signature Verification
- Constant-time comparison to prevent timing attacks
- Support for multiple signature algorithms
- Provider-specific signature formats
Replay Protection
- Timestamp validation with configurable tolerance
- Request rate limiting support
Input Validation
- JSON payload validation
- Header sanitization
- Content-Type verification
Error Handling
The validator returns detailed error information:
if (!result.valid) {
result.errors.forEach(error => {
console.log(`${error.type}: ${error.message} (${error.code})`);
if (error.details) {
console.log('Details:', error.details);
}
});
}Common error codes:
MISSING_SIGNATURE- Required signature header is missingINVALID_SIGNATURE- Signature verification failedINVALID_JSON- Payload is not valid JSONTIMESTAMP_TOO_OLD- Timestamp outside acceptable range
Provider Support
GitHub
- Validates
x-hub-signature-256andx-hub-signatureheaders - Checks User-Agent header
- Validates repository structure
Stripe
- Handles timestamp-based signatures from
stripe-signatureheader - Validates event structure
- Enforces timestamp requirements
SendGrid
- Validates
x-twilio-email-event-webhook-signatureheader - Handles timestamp headers
- Validates event array structure
License
Copyright (c) 2025 Bernier LLC. All rights reserved.
