#21532: Security/Voice Call: block signed webhook replay
channel: voice-call
size: S
Cluster:
Security Enhancements and Guardrails
## Summary
- split signed-webhook replay protection out of #21203 into a dedicated voice-call security PR
- dedupe replayed signed webhook requests before event processing for Telnyx/Plivo/Twilio signature flows
- add focused replay-protection tests in `extensions/voice-call/src/webhook.test.ts`
## Scope boundaries
- intentionally excludes exact-path matching changes (tracked separately)
- intentionally excludes host-header hardening changes (tracked separately)
- intentionally excludes Control UI and non-voice webhook replay work
## Validation
- pnpm test -- extensions/voice-call/src/webhook.test.ts
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR adds webhook replay protection for voice call webhooks from Telnyx, Plivo, and Twilio providers. The implementation creates a fingerprint from provider-specific signature headers and idempotency tokens, then tracks seen requests in a 5-minute sliding window using an in-memory Map. Replayed webhooks are dropped after signature verification but before event processing.
Key changes:
- Adds `buildReplayKey()` to construct provider-specific replay keys from signature headers and nonces/timestamps
- Implements `shouldDropReplayWebhook()` with SHA-256 fingerprinting and 5-minute window deduplication
- Maintains `recentReplayKeys` map with automatic cleanup when exceeding 5000 entries
- Test coverage for replay protection with identical Telnyx webhook requests
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The implementation is well-designed with proper separation of concerns, comprehensive test coverage, and correct replay detection logic. The code follows the repository's patterns, includes appropriate memory management (map cleanup), and maintains security by performing replay checks after signature verification. The 5-minute window and 5000-key limit provide reasonable protection without excessive memory usage.
- No files require special attention
<sub>Last reviewed commit: e15d73d</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#21531: Security/Webhooks: block signed replay for Nextcloud, Google Chat, ...
by bmendonca3 · 2026-02-20
84.6%
#6128: Fail closed when Telnyx webhook public key is missing (voice-call p...
by yueyueL · 2026-02-01
78.4%
#21197: Security/Voice Call: enforce exact webhook path matching
by bmendonca3 · 2026-02-19
77.1%
#21101: Security/Voice Call: gate skipSignatureVerification to local-dev or...
by bmendonca3 · 2026-02-19
76.1%
#21128: Security/Voice Call: require trusted proxy IPs for forwarded-header...
by bmendonca3 · 2026-02-19
75.7%
#7704: fix(voice-call): add authentication to WebSocket media stream endpoint
by coygeek · 2026-02-03
75.1%
#10239: Security: Add production guard for skipSignatureVerification
by StreetJammer · 2026-02-06
74.1%
#23461: Gateway: add hook replay protection with timestamp and nonce
by bmendonca3 · 2026-02-22
73.4%
#21288: Security/Voice: reject malformed Host headers in webhook+WS server
by bmendonca3 · 2026-02-19
73.0%
#21050: security(voice-call): path-based stream token for Twilio WebSocket ...
by richvincent · 2026-02-19
73.0%