Fix Insecure Webhooks in Fresh
Fresh routes are public by design. If your webhook handlers don't verify incoming signatures, you're inviting attackers to spoof events, bypass logic, and manipulate your backend. Insecure webhooks are a low-effort entry point for unauthorized state changes. Stop trusting the 'origin' header and start using HMAC verification.
The Vulnerable Pattern
import { Handlers } from "$fresh/server.ts";export const handler: Handlers = { async POST(req) { // VULNERABLE: No signature verification. // Anyone can POST any JSON to this endpoint. const body = await req.json(); console.log(“Processing event:”, body.type);
return new Response("Accepted", { status: 200 });
} };
The Secure Implementation
The vulnerable snippet blindly trusts the request body. An attacker can replay old requests or forge new ones to trigger business logic. The secure implementation uses the Web Crypto API to perform a constant-time HMAC SHA-256 verification. It extracts the raw body as text—not JSON—to ensure the cryptographic hash matches exactly what the provider signed. If the signature is missing or invalid, it returns a 401 Unauthorized, neutralizing the attack vector.
import { Handlers } from "$fresh/server.ts";const WEBHOOK_SECRET = Deno.env.get(“WEBHOOK_SECRET”);
async function verify(payload: string, sig: string): Promise
{ if (!WEBHOOK_SECRET) return false; const encoder = new TextEncoder(); const key = await crypto.subtle.importKey( “raw”, encoder.encode(WEBHOOK_SECRET), { name: “HMAC”, hash: “SHA-256” }, false, [“verify”] ); const sigBytes = new Uint8Array(sig.match(/.{1,2}/g)!.map(byte => parseInt(byte, 16))); return await crypto.subtle.verify(“HMAC”, key, sigBytes, encoder.encode(payload)); } export const handler: Handlers = { async POST(req) { const signature = req.headers.get(“x-hub-signature-256”)?.replace(“sha256=”, ""); const rawBody = await req.text();
if (!signature || !(await verify(rawBody, signature))) { return new Response("Signature mismatch", { status: 401 }); } const data = JSON.parse(rawBody); return new Response("Verified", { status: 200 });
} };
Your Fresh API
might be exposed to Insecure Webhooks
74% of Fresh 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.