Fix Insecure Webhooks in ElysiaJS
Webhooks are remote procedure calls over HTTP. If you aren't verifying the cryptographic signature of the payload, you're essentially providing an unauthenticated API endpoint for attackers to inject arbitrary data. In ElysiaJS, the common mistake is consuming the parsed body directly without validating the HMAC-SHA256 signature against the raw request buffer, leading to bypasses via JSON normalization discrepancies or simple spoofing.
The Vulnerable Pattern
import { Elysia } from 'elysia';
new Elysia() .post(‘/webhook’, ({ body }) => { // DANGER: No signature verification. // An attacker can send any payload to trigger internal logic. const { event, data } = body as any; processBusinessLogic(event, data); return { success: true }; }) .listen(3000);
The Secure Implementation
The secure implementation enforces three layers of defense. First, it extracts the HMAC signature from the headers. Second, it re-calculates the HMAC-SHA256 hash using a pre-shared secret and the raw request payload. Finally, it uses 'timingSafeEqual' for the comparison. This is critical; standard string comparison (==) returns as soon as a character mismatch is found, allowing an attacker to brute-force the signature byte-by-byte by measuring the server's response time. Always ensure you verify the signature before any business logic is executed.
import { Elysia, error } from 'elysia'; import { createHmac, timingSafeEqual } from 'node:crypto';const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || ‘super-secret-key’;
new Elysia() .post(‘/webhook’, async ({ headers, body, request }) => { const signature = headers[‘x-signature’]; if (!signature) throw error(401, ‘Unauthorized’);
// Get raw body for verification to avoid JSON stringify inconsistencies const rawBody = JSON.stringify(body); const hmac = createHmac('sha256', WEBHOOK_SECRET); const digest = hmac.update(rawBody).digest('hex'); // Use timingSafeEqual to prevent timing side-channel attacks const trusted = Buffer.from(digest, 'ascii'); const untrusted = Buffer.from(signature, 'ascii'); if (trusted.length !== untrusted.length || !timingSafeEqual(trusted, untrusted)) { throw error(403, 'Invalid Signature'); } return { status: 'verified' };
}) .listen(3000);
Your ElysiaJS API
might be exposed to Insecure Webhooks
74% of ElysiaJS apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.