Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosGoogle Cloud Tech: Gemini is coming to your city(24.09.2026 um 15:00 Uhr)
AI & KI NachrichtenGoogle’s latest moonshot to put machine learning in space(24.09.2026 um 15:12 Uhr)
Windows Tipps & SecurityPoll: What's your favorite Surface of 2026?(24.09.2026 um 14:58 Uhr)
Sichere ProgrammierungStreaming Materialized Views for Live Read Models (2026)(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungA Day Is Not 86400 Seconds: The DST Bug in Your Date Math(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungSetting up Traefik: reverse proxy with automatic HTTPS(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungA 200 OK response does not prove a secret leak(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungHow hot do you like it?(24.09.2026 um 15:05 Uhr)
YouTube Security VideosGoogle Cloud Tech: Gemini is coming to your city(24.09.2026 um 15:00 Uhr)
AI & KI NachrichtenGoogle’s latest moonshot to put machine learning in space(24.09.2026 um 15:12 Uhr)
Windows Tipps & SecurityPoll: What's your favorite Surface of 2026?(24.09.2026 um 14:58 Uhr)
Sichere ProgrammierungStreaming Materialized Views for Live Read Models (2026)(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungA Day Is Not 86400 Seconds: The DST Bug in Your Date Math(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungSetting up Traefik: reverse proxy with automatic HTTPS(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungA 200 OK response does not prove a secret leak(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungHow hot do you like it?(24.09.2026 um 15:05 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

If a bank hired me to fix their webhook handling, here is how NestJS would help me start

A bank or payment provider sends a webhook the moment something happens. A transfer completes, a payment settles, a dispute is opened. The backend receiving that webhook is supposed to update its records and move on. Simple in theory. In…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

A bank or payment provider sends a webhook the moment something happens. A transfer completes, a payment settles, a dispute is opened. The backend receiving that webhook is supposed to update its records and move on. Simple in theory.



In practice, the same webhook often arrives more than once. The provider's server times out waiting for a response, assumes the delivery failed, and sends it again. Now the backend has processed the same event twice. If that event triggered sending a confirmation email, the customer gets two emails. If it triggered releasing funds or updating an account balance, that is a much bigger problem, and the kind of bug that does not show up in testing, only under real load with real retries.



If I walked into a bank or fintech company and found this happening, this is exactly how I would think through fixing it using NestJS.






Why this keeps happening



Most payment providers, from Stripe to Worldpay to bank transfer rails, use what is called at least once delivery. They do not promise to send an event exactly once. They promise to keep retrying until they get a successful response. This means duplicates are not a bug on their end, they are expected behavior on your end that has to be handled.



The mistake I see most often is a webhook handler that assumes every request it receives is a brand new event.




@Controller('webhooks')
export class WebhooksController {
constructor(private readonly transactionsService: TransactionsService) {}

@Post('payment-provider')
async handleWebhook(@Body() payload: PaymentWebhookDto) {
await this.transactionsService.markSettled(payload.transactionId);
return { received: true };
}
}






This works the first time an event arrives. It quietly breaks the moment that same event arrives a second time, because nothing here checks whether it has already been processed.






Verifying the webhook actually came from the provider



Before anything else, I would make sure the request is genuine. Anyone can send a POST request to a public endpoint. Providers sign their webhook payloads with a shared secret, usually using HMAC, and expect you to verify that signature before trusting anything in the body.




@Injectable()
export class WebhookSignatureGuard implements CanActivate {
constructor(private readonly configService: ConfigService) {}

canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
const signature = request.headers['x-provider-signature'];
const secret = this.configService.get('WEBHOOK_SECRET');

const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(request.body))
.digest('hex');

if (signature !== expectedSignature) {
throw new UnauthorizedException('Invalid webhook signature');
}

return true;
}
}






This becomes a guard sitting in front of the webhook route, so nothing unverified even reaches the handler.






Making the handler safe to run more than once



Once the request is verified, the next step is deduplication. Every well designed webhook includes a unique event ID that stays the same across retries. I would store that ID the first time it is seen, and skip processing entirely if it shows up again.




@Controller('webhooks')
@UseGuards(WebhookSignatureGuard)
export class WebhooksController {
constructor(
private readonly webhookEventsService: WebhookEventsService,
@InjectQueue('webhook-processing') private readonly webhookQueue: Queue,
) {}

@Post('payment-provider')
async handleWebhook(@Body() payload: PaymentWebhookDto) {
const alreadySeen = await this.webhookEventsService.exists(payload.eventId);

if (alreadySeen) {
return { received: true };
}

await this.webhookEventsService.recordEvent(payload.eventId);
await this.webhookQueue.add('process', payload);

return { received: true };
}
}






Notice that the response is returned quickly, right after the event is recorded and queued, not after the full processing is done. Providers expect a fast response, usually within a few seconds. If your handler takes too long doing the actual work before responding, the provider assumes failure and retries an event that already succeeded, which brings you right back to duplicates. Acknowledging quickly and processing separately avoids that trap entirely.



The recordEvent call should rely on a unique constraint at the database level, not just an application level check, since two identical webhook deliveries can arrive close enough together that a simple check and insert has a race condition.




@Entity()
export class WebhookEvent {
@PrimaryColumn()
eventId: string;

@CreateDateColumn()
receivedAt: Date;
}






With eventId as the primary column, a second insert attempt for the same event fails at the database level, which is a much safer guarantee than checking first and inserting second.






Doing the actual work in the background



The queue processor is where the real update happens, completely separate from the request that came in from the provider.




@Processor('webhook-processing')
export class WebhookProcessor {
constructor(private readonly transactionsService: TransactionsService) {}

@Process('process')
async handleWebhookEvent(job: Job<PaymentWebhookDto>) {
const { transactionId, status } = job.data;

if (status === 'settled') {
await this.transactionsService.markSettled(transactionId);
}

if (status === 'failed') {
await this.transactionsService.markFailed(transactionId);
}
}
}






If this step fails for any reason, BullMQ retry settings handle trying again, without the provider needing to resend anything or the bank facing a repeated webhook storm.






The bigger picture



NestJS will not stop a payment provider from retrying webhooks, and it should not try to. Retries are the provider protecting itself against uncertainty. What NestJS gives you is a clean place to put each responsibility, a guard for verifying the request is genuine, a service for tracking what has already been seen, and a queue for doing the actual work safely away from the response cycle. None of these pieces are complicated on their own. What matters is that the structure makes it hard to skip any of them by accident, which is usually how these bugs get into production in the first place.



If your team is dealing with webhook reliability issues, duplicate processing, or anything similar around payment events, I would be glad to talk through how to restructure it.



I am Peace Melodi, a backend software engineer. If you want your business to scale big, comfortably handling millions of users without breaking, with strong scalability and security in place, feel free to reach out.



LinkedIn: https://www.linkedin.com/in/melodi-peace-406494368

GitHub: https://github.com/PeaceMelodi

CTI Threat Relationship Graph2 Knoten / 1 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
SOC Incident Playbook: Vulnerability Remediation & Verification
title: Detect Exploitation - If a bank hired me to fix their webhook handling, here is how NestJS would help me start
id: 2afa8f59-1784-4755-9159-3a6ca3c020de
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-24
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-24"
        description = "YARA Signature for "
    strings:
        $str = "If a bank hired me to fix thei" ascii wide
    condition:
        any of them
}
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich If a bank hired me to fix their webhook .... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten If a bank hired me to fix their webhook handling, here is how NestJS would help me start

Thematisch verwandte Begriffe: bank, hired, their, webhook · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-97152 | Nanomsg versions 0.5-beta through 1.x before 1.2.3 has a remotely exploi…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel TTP ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick