mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-10 13:31:38 +00:00
fix(webhook): rate-limit V1 deprecation warning + document V2 signature
- warn once per route instead of on every request (busy senders would spam the log) - document X-Webhook-Signature-V2 / X-Webhook-Timestamp in the webhooks user guide Follow-ups for salvaged #58461.
This commit is contained in:
parent
70449a4939
commit
708b57e009
2 changed files with 16 additions and 9 deletions
|
|
@ -121,6 +121,9 @@ class WebhookAdapter(BasePlatformAdapter):
|
|||
self._dynamic_routes_mtime: float = 0.0
|
||||
self._routes: Dict[str, dict] = dict(self._static_routes)
|
||||
self._runner = None
|
||||
# Routes already warned about legacy V1 body-only signatures
|
||||
# (once-per-route so a busy sender doesn't spam the log).
|
||||
self._v1_signature_warned: set[str] = set()
|
||||
|
||||
# Delivery info keyed by session chat_id.
|
||||
#
|
||||
|
|
@ -913,14 +916,17 @@ class WebhookAdapter(BasePlatformAdapter):
|
|||
expected = hmac.new(
|
||||
secret.encode(), body, hashlib.sha256
|
||||
).hexdigest()
|
||||
logger.warning(
|
||||
"[webhook] Route '%s' uses legacy body-only HMAC (no "
|
||||
"timestamp), which is vulnerable to replay attacks. Add "
|
||||
"an 'X-Webhook-Timestamp' header and switch to "
|
||||
"'X-Webhook-Signature-V2' (HMAC-SHA256 of "
|
||||
"'<timestamp>.<body>').",
|
||||
request.match_info.get("route_name", ""),
|
||||
)
|
||||
route_name = request.match_info.get("route_name", "")
|
||||
if route_name not in self._v1_signature_warned:
|
||||
self._v1_signature_warned.add(route_name)
|
||||
logger.warning(
|
||||
"[webhook] Route '%s' uses legacy body-only HMAC (no "
|
||||
"timestamp), which is vulnerable to replay attacks. Add "
|
||||
"an 'X-Webhook-Timestamp' header and switch to "
|
||||
"'X-Webhook-Signature-V2' (HMAC-SHA256 of "
|
||||
"'<timestamp>.<body>').",
|
||||
route_name,
|
||||
)
|
||||
return hmac.compare_digest(generic_sig, expected)
|
||||
|
||||
# No recognised signature header but secret is configured → reject
|
||||
|
|
|
|||
|
|
@ -387,7 +387,8 @@ The adapter validates incoming webhook signatures using the appropriate method f
|
|||
|
||||
- **GitHub**: `X-Hub-Signature-256` header — HMAC-SHA256 hex digest prefixed with `sha256=`
|
||||
- **GitLab**: `X-Gitlab-Token` header — plain secret string match
|
||||
- **Generic**: `X-Webhook-Signature` header — raw HMAC-SHA256 hex digest
|
||||
- **Generic (V2, recommended)**: `X-Webhook-Signature-V2` + `X-Webhook-Timestamp` headers — HMAC-SHA256 hex digest of `<timestamp>.<body>`. The timestamp (Unix seconds) must be within ±300 seconds of the server clock, which prevents captured requests from being replayed later.
|
||||
- **Generic (V1, legacy)**: `X-Webhook-Signature` header — raw HMAC-SHA256 hex digest of the body only. Still accepted for backward compatibility, but it has no replay protection (a captured request replays indefinitely); the gateway logs a deprecation warning once per route. Switch senders to V2.
|
||||
|
||||
If a secret is configured but no recognized signature header is present, the request is rejected.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue