Fix Insecure Webhooks in Nitro
Webhooks in Nitro are often the weakest link in the chain. Without signature verification, your endpoint is a public API allowing anyone to spoof events, manipulate business logic, or trigger unauthorized actions. If you're using 'readBody' and trusting the payload based on zero proof, you're pwned by design.
The Vulnerable Pattern
export default defineEventHandler(async (event) => {
const body = await readBody(event);
// VULNERABILITY: Blindly trusting the incoming body without origin verification
await updateDatabase(body.userId, { status: 'premium' });
return { success: true };
});
The Secure Implementation
To secure Nitro webhooks, you must verify the HMAC signature provided by the sender. 1. Use 'readRawBody' instead of 'readBody' because any middleware that parses the JSON beforehand will alter the byte-for-byte representation required for hashing. 2. Use 'crypto.timingSafeEqual' to compare the computed hash against the header signature; this prevents timing attacks that could leak the secret character by character. 3. Always store your webhook secret in environment variables, never hardcoded.
import { createHmac, timingSafeEqual } from 'node:crypto';export default defineEventHandler(async (event) => { const signature = getHeader(event, ‘x-webhook-signature’); const secret = process.env.WEBHOOK_SECRET;
if (!signature || !secret) { throw createError({ statusCode: 401, statusMessage: ‘Unauthorized’ }); }
// Use readRawBody to ensure we hash the exact bytes received const rawBody = await readRawBody(event); const hmac = createHmac(‘sha256’, secret); const digest = Buffer.from(hmac.update(rawBody).digest(‘hex’), ‘utf8’); const checksum = Buffer.from(signature, ‘utf8’);
if (checksum.length !== digest.length || !timingSafeEqual(digest, checksum)) { throw createError({ statusCode: 401, statusMessage: ‘Invalid Signature’ }); }
const body = JSON.parse(rawBody.toString()); await updateDatabase(body.userId, { status: ‘premium’ }); return { success: true }; });
Your Nitro API
might be exposed to Insecure Webhooks
74% of Nitro 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.