← Back to PRs

#23461: Gateway: add hook replay protection with timestamp and nonce

by bmendonca3 open 2026-02-22 10:16 View on GitHub →
gateway size: M trusted-contributor
## 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