mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-20 18:11:48 +00:00
fix(sms): replayed Twilio webhooks process again after high inbound traffic (#101107)
* fix(sms): replayed Twilio webhooks process again after high inbound traffic * fix(sms): harden Twilio replay saturation * test(sms): expose response header spy --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -343,7 +343,7 @@ The first message should create a pairing request. The second message should rec
|
||||
|
||||
## Webhook security
|
||||
|
||||
By default, OpenClaw validates `X-Twilio-Signature` using `publicWebhookUrl` and `authToken`. Keep `publicWebhookUrl` byte-for-byte aligned with the URL configured in Twilio, including scheme, host, path, and query string.
|
||||
By default, OpenClaw validates `X-Twilio-Signature` using `publicWebhookUrl` and `authToken`. Keep the endpoint portion of `publicWebhookUrl` byte-for-byte aligned with the URL configured in Twilio, including scheme, host, path, and query string. OpenClaw excludes Twilio [connection-override](https://www.twilio.com/docs/usage/webhooks/webhooks-connection-overrides) fragments (`#...`) from signature computation, as Twilio requires.
|
||||
|
||||
The webhook route also enforces, independent of signature validation:
|
||||
|
||||
@@ -351,8 +351,11 @@ The webhook route also enforces, independent of signature validation:
|
||||
- Rate limit of 30 requests per minute per source IP (HTTP 429 above that).
|
||||
- The payload `AccountSid` must match the configured `accountSid` (HTTP 403 otherwise).
|
||||
- Replayed `MessageSid` values are deduplicated for 10 minutes.
|
||||
- Each SMS account's replay cache retains up to 10,000 live message SIDs. When every slot is live, new webhooks for that account fail closed with HTTP 429 and a `Retry-After` header until the oldest slot expires.
|
||||
- Request bodies over 32 KB are rejected.
|
||||
|
||||
Twilio does not retry HTTP 429 by default or document support for `Retry-After`. The `#rp=4xx` and `#rp=all` connection overrides opt into 4xx retries, but Twilio caps the complete retry transaction at 15 seconds, so retries can still finish before a replay-cache slot expires. Configure a fallback URL when another handler must receive failed deliveries; treat a 429 as a fail-closed rejection, not reliable backpressure.
|
||||
|
||||
For local tunnel testing only, you can set:
|
||||
|
||||
```json5
|
||||
|
||||
Reference in New Issue
Block a user