Webhooks
Also Known As
HTTP callback
webhook endpoint
push notification HTTP
TL;DR
A reverse API — a service POSTs event notifications to a registered URL whenever something occurs, eliminating the need to poll.
Explanation
Webhooks enable event-driven integrations: instead of your application polling an API every minute, the service POSTs a JSON payload to your endpoint the moment an event fires (payment.completed, push.received). Implementing a receiver: expose a public HTTPS endpoint, verify the payload signature (HMAC-SHA256 of the body against a shared secret, constant-time comparison with hash_equals()), respond with 200 immediately, and queue actual processing asynchronously to avoid delivery timeouts. Sending webhooks: store endpoint URLs per customer, deliver with retry and exponential backoff, record all delivery attempts, and support manual replay for debugging.
Common Misconception
✗ Webhooks are always more efficient than polling. Webhooks push events immediately but require a publicly reachable endpoint, reliable delivery handling, and signature verification. Polling is simpler and sometimes more appropriate for batch processing or when strict ordering matters.
Why It Matters
Webhooks deliver real-time event notifications via HTTP POST — they invert the polling model, but require validation, idempotency, and failure handling that polling naturally provides.
Common Mistakes
- Not validating the webhook signature — any HTTP client can send a fake payload to your endpoint.
- Not returning HTTP 200 quickly and processing asynchronously — slow handlers cause the sender to retry, duplicating events.
- Not handling duplicate delivery — webhook senders retry on timeout or non-2xx; your handler must be idempotent.
- Not logging raw payloads — debugging webhook failures requires the original body.
Avoid When
- The consumer cannot guarantee idempotent processing — duplicate deliveries will cause duplicate side effects.
- The payload contains sensitive data sent to an unverified URL — always validate signatures and use HTTPS.
- The receiving server is unreliable — webhooks can be lost; use a message queue for guaranteed delivery.
- You need request-reply semantics — webhooks are fire-and-forget; use polling or SSE for two-way flow.
When To Use
- Notifying external systems of events in real time without them needing to poll.
- Integrating with third-party platforms (Stripe, GitHub, Shopify) that push events on state changes.
- Triggering CI pipelines, cache purges, or downstream workflows in response to your own events.
- Replacing polling in scenarios where events are infrequent and latency matters.
Code Examples
✗ Vulnerable
// No signature validation — accepts any POST as legitimate:
app()->post('/webhook', function(Request $req): Response {
processEvent($req->json()); // No HMAC verification
return response('ok', 200);
});
// Add: hash_equals(hash_hmac('sha256', $req->rawBody(), $secret), $req->header('X-Signature'))
✓ Fixed
// Verify Stripe webhook signature
$payload = file_get_contents('php://input');
$sig = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = \Stripe\Webhook::constructEvent($payload, $sig, $secret);
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
25 Mar 2026
Views
44
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
Perplexity 15
Amazonbot 13
Google 6
ChatGPT 4
Unknown AI 3
Ahrefs 2
Meta AI 1
Also referenced
How they use it
crawler 39
crawler_json 5
Related categories
⚡
DEV INTEL
Tools & Severity
🟡 Medium
⚙ Fix effort: Medium
⚡ Quick Fix
Define webhook payloads as versioned typed events, verify HMAC signatures on every delivery, and respond 200 immediately — do processing asynchronously in a queue
📦 Applies To
PHP 5.0+
web
api
🔗 Prerequisites
🔍 Detection Hints
Webhook handler doing heavy processing synchronously; no HMAC signature verification; webhook endpoint not responding within 5 seconds
Auto-detectable:
✗ No
semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: File
Tests: Update
CWE-345
CWE-352