You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Background
The dashboard exposes a webhook endpoint that verifies x-guildpass-signature using @guildpass/webhook-utils before processing events like member.joined and pass.activated. The webhook-utils README's security best-practices section covers signature and secret handling, but says nothing about protecting the endpoint itself from abuse (flooding, oversized payloads, or scripted probing of the signature-verification logic).
Problem
An unauthenticated (pre-signature-check) request to the webhook endpoint currently has no request-size ceiling or rate limit ahead of the cryptographic verification step, meaning a malicious or misbehaving client could send excessively large bodies or a high volume of invalid-signature requests, consuming CPU on repeated HMAC computations and buffering large payloads before rejection — and there's no structured log trail to distinguish "someone is probing this endpoint" from ordinary transient failures.
Expected outcome
The webhook route rejects oversized request bodies before attempting signature verification, applies a sensible rate limit per source IP (or another available signal) for repeated invalid-signature attempts, and logs rejections in a structured format (reason, timestamp, source, but never the secret or a valid signature value) suitable for later alerting.
Suggested implementation
Add a body-size guard (e.g. reject bodies over a configurable limit, such as 256KB, with a 413 before parsing/verifying).
Add a lightweight in-process (or storage-backed, reusing Issue Add timeout support to IntegrationClient #8's abstraction) rate limiter keyed by source IP + endpoint, returning 429 once a threshold of invalid-signature attempts is exceeded within a window.
Emit structured log entries (JSON) for every rejection with a reason enum (oversized_payload, invalid_signature, expired_timestamp, rate_limited, malformed_header) — reusing/extending the existing error categories already returned by verifySignature.
Document the new limits and log format in SECURITY.md and packages/webhook-utils/README.md's "Security Best Practices" section (cross-referenced, since the limiting logic likely lives in the dashboard's route, not the package itself).
Acceptance criteria
Requests over the configured size limit are rejected before signature verification runs, with a clear status code.
Repeated invalid-signature attempts from the same source within a window trigger rate limiting.
Rejections are logged in a consistent structured format without ever logging the raw secret or a valid signature.
Legitimate webhook traffic at normal volume is unaffected (tests demonstrate the limiter doesn't trigger under expected load).
pnpm --filter @guildpass/dashboard test passes, including new tests for size limiting and rate limiting.
Difficulty: Advanced
Type: Security
Background
The dashboard exposes a webhook endpoint that verifies
x-guildpass-signatureusing@guildpass/webhook-utilsbefore processing events likemember.joinedandpass.activated. The webhook-utils README's security best-practices section covers signature and secret handling, but says nothing about protecting the endpoint itself from abuse (flooding, oversized payloads, or scripted probing of the signature-verification logic).Problem
An unauthenticated (pre-signature-check) request to the webhook endpoint currently has no request-size ceiling or rate limit ahead of the cryptographic verification step, meaning a malicious or misbehaving client could send excessively large bodies or a high volume of invalid-signature requests, consuming CPU on repeated HMAC computations and buffering large payloads before rejection — and there's no structured log trail to distinguish "someone is probing this endpoint" from ordinary transient failures.
Expected outcome
The webhook route rejects oversized request bodies before attempting signature verification, applies a sensible rate limit per source IP (or another available signal) for repeated invalid-signature attempts, and logs rejections in a structured format (reason, timestamp, source, but never the secret or a valid signature value) suitable for later alerting.
Suggested implementation
413before parsing/verifying).IntegrationClient#8's abstraction) rate limiter keyed by source IP + endpoint, returning429once a threshold of invalid-signature attempts is exceeded within a window.reasonenum (oversized_payload,invalid_signature,expired_timestamp,rate_limited,malformed_header) — reusing/extending the existing error categories already returned byverifySignature.SECURITY.mdandpackages/webhook-utils/README.md's "Security Best Practices" section (cross-referenced, since the limiting logic likely lives in the dashboard's route, not the package itself).Acceptance criteria
pnpm --filter @guildpass/dashboard testpasses, including new tests for size limiting and rate limiting.Likely affected files/directories
Webhook route handler (
apps/dashboard/app/api/webhook*/),SECURITY.md,packages/webhook-utils/README.md, new rate-limiting utility module.