#23461: Gateway: add hook replay protection with timestamp and nonce
gateway
size: M
trusted-contributor
Cluster:
Security Enhancements and Guardrails
## Summary
- add opt-in webhook replay protection via `hooks.requireTimestamp`
- require `X-OpenClaw-Timestamp` + `X-OpenClaw-Nonce` when enabled
- reject stale timestamps outside the allowed window (default 5 minutes)
- reject repeated nonces with an in-memory bounded replay cache (`hooks.replayCacheSize`)
- add config/schema support and unit/e2e coverage for replay/stale checks
## Why
This hardens exposed/tunneled hook endpoints against bearer-token replay by binding requests to a short time window and one-time nonce semantics.
## Testing
- `pnpm test src/gateway/hooks.test.ts`
- `pnpm test src/gateway/server-http.hooks-request-timeout.test.ts`
- `pnpm test src/config/config-misc.test.ts`
- `pnpm test:e2e src/gateway/server.hooks.e2e.test.ts`
- `pnpm check`
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds opt-in webhook replay protection via `hooks.requireTimestamp` to prevent bearer token replay attacks. When enabled, requires `X-OpenClaw-Timestamp` and `X-OpenClaw-Nonce` headers, rejects stale timestamps outside a 5-minute window, and tracks nonces in a bounded in-memory cache (`hooks.replayCacheSize`, default 1024) to prevent replays.
**Key changes:**
- New config options: `requireTimestamp` (boolean) and `replayCacheSize` (positive integer)
- Timestamp validation supports both unix seconds and milliseconds
- Nonce cache uses Map insertion order for FIFO eviction
- Comprehensive test coverage for replay detection, stale timestamps, and configuration
- Appropriate HTTP status codes: 409 for replays, 401 for stale timestamps, 400 for missing/invalid headers
<h3>Confidence Score: 5/5</h3>
- Safe to merge - well-implemented security hardening with comprehensive tests
- Implementation follows security best practices with proper validation, bounded cache to prevent memory exhaustion, comprehensive test coverage including unit and e2e tests for replay/stale scenarios, opt-in design prevents breaking changes, and uses appropriate HTTP status codes. The code is clean, well-structured, and the timestamp window (5 minutes) is reasonable for webhook scenarios.
- No files require special attention
<sub>Last reviewed commit: bbd727b</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#6405: feat(security): Add HTTP API security hooks for plugin scanning
by masterfung · 2026-02-01
75.8%
#23447: Gateway: harden hook ingress content-type validation
by bmendonca3 · 2026-02-22
74.9%
#23355: Gateway: fail closed on untrusted proxy headers
by bmendonca3 · 2026-02-22
74.6%
#12635: Gateway: add inbound webhook dispatch framework
by jhs129 · 2026-02-09
74.4%
#23765: Gateway hooks: enforce JSON content type and strict payload keys
by bmendonca3 · 2026-02-22
74.0%
#23410: Gateway: require prefixes for hook request session-key overrides
by bmendonca3 · 2026-02-22
73.9%
#8121: fix(gateway): remove query parameter token support for hooks
by yubrew · 2026-02-03
73.7%
#21532: Security/Voice Call: block signed webhook replay
by bmendonca3 · 2026-02-20
73.4%
#13144: harden archive extraction, auth tokens, hook transforms, and queue ...
by qxlsz · 2026-02-10
73.2%
#23763: Hooks: require session key prefixes for request override
by bmendonca3 · 2026-02-22
73.1%