GuardAPI Logo
GuardAPI

Fix Insecure Webhooks in LoopBack

Webhooks are essentially unauthenticated POST endpoints unless you implement cryptographic verification. In LoopBack applications, accepting webhook payloads without validating the source signature allows attackers to spoof events, manipulate internal state, or bypass business logic. To harden this, you must enforce HMAC (Hash-based Message Authentication Code) verification using a shared secret and timing-safe comparisons.

The Vulnerable Pattern

import {post, requestBody} from '@loopback/rest';

export class WebhookController { @post(‘/webhooks/stripe’) async handle(@requestBody() payload: any): Promise { // VULNERABLE: No signature verification. // Anyone can POST any JSON to this endpoint to trigger logic. if (payload.type === ‘charge.succeeded’) { await this.fulfillOrder(payload.data.object.id); } } }

The Secure Implementation

The secure implementation introduces a cryptographic handshake. 1. Shared Secret: We use a secret key known only to the provider and our app. 2. HMAC Generation: We hash the incoming request body using SHA-256. 3. Constant-Time Comparison: We use crypto.timingSafeEqual instead of a standard equality operator (==) to prevent attackers from guessing the signature via response time variances. This ensures that only the legitimate provider can trigger the webhook logic.

import {post, requestBody, HttpErrors, Request, RestBindings} from '@loopback/rest';
import {inject} from '@loopback/core';
import * as crypto from 'crypto';

export class WebhookController { constructor(@inject(RestBindings.Http.REQUEST) private req: Request) {}

@post(‘/webhooks/stripe’) async handle(@requestBody() payload: any): Promise { const signature = this.req.headers[‘x-hub-signature-256’] as string; const secret = process.env.WEBHOOK_SECRET || ”;

if (!signature) throw new HttpErrors.Unauthorized('Missing Signature');

// Recompute HMAC using the raw body and shared secret
const hmac = crypto.createHmac('sha256', secret);
const digest = Buffer.from('sha256=' + hmac.update(JSON.stringify(payload)).digest('hex'), 'utf8');
const checksum = Buffer.from(signature, 'utf8');

// Use timingSafeEqual to mitigate timing side-channel attacks
if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) {
  throw new HttpErrors.Unauthorized('Invalid Signature');
}

await this.processVerifiedEvent(payload);

} }

System Alert • ID: 8443
Target: LoopBack API
Potential Vulnerability

Your LoopBack API might be exposed to Insecure Webhooks

74% of LoopBack apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.