Skip to content

Add stricter per-route limits and challenge-griefing protection on /auth/challenge and /auth/verify #369

Closed

Description

@meshackyaro

Description

Builds on #37, #168 and #208. A global RateLimitGuard (backend/src/common/rate-limit/rate-limit.guard.ts, registered as APP_GUARD in rate-limit.module.ts) already applies a Redis token bucket per IP and per wallet, tracks repeated violations in a sliding abuse window (RATE_LIMIT_ABUSE_*, RATE_LIMIT_LOCKOUT_SECONDS in config/env.config.ts) and returns 429 with retryAfter and scope. @RateLimit(points, duration) and @SkipRateLimit() decorators exist for per-route overrides.

AuthController (backend/src/auth/auth.controller.ts) uses neither decorator, so GET /auth/challenge and POST /auth/verify fall under the same default as every other route (100 requests per 60 s per IP). The specific gaps that remain:

  • No stricter, auth-specific limits, on either route.
  • NonceStoreService.store() (auth/nonce-store.service.ts) keeps one pending challenge per address and replaces it on each new request, so anyone can repeatedly call /auth/challenge?address=<victim> and invalidate the victim's in-flight login. The wallet identity in the guard (extractWallet) comes from the unauthenticated query.address / body.address on these routes, so it cannot be relied on as a per-address limiter (see RateLimitGuard's wallet-scoped identity can be spoofed via unauthenticated request fields #208).
  • main.ts does not set Express trust proxy, so behind a load balancer request.ip may be the proxy address and every client could share one IP bucket.
  • A 429 carries only a JSON body: no Retry-After / X-RateLimit-* headers are set, and the guard never logs when it rejects a request (its only log line is the "Redis not configured" warning), so violations are invisible.

Component

Backend

Difficulty

🟡 Medium

Tasks

  • Add auth-specific @RateLimit() values to /auth/challenge and /auth/verify (configurable via env) that are stricter than the global default
  • Limit pending challenges per address (e.g. do not replace an existing live challenge, or cap challenge issuance per address per minute) so a third party cannot cancel someone else's login
  • Decide and document the trust proxy setting for deployments behind a load balancer so the IP bucket is per client
  • Log rate-limit rejections (scope, route, masked identity) and emit a metric
  • Set Retry-After (and X-RateLimit-* if desired) on 429 responses
  • Tests: repeated /auth/challenge calls from one IP hit 429 at the configured threshold; the pending-challenge protection holds

Acceptance Criteria

  • /auth/challenge and /auth/verify enforce their own limits, independent of the global default
  • A client cannot invalidate another wallet's pending challenge by requesting new ones
  • 429 responses include Retry-After and each rejection is logged
  • Proxy/IP handling is documented

Estimated Time

1-2 days

Activity

  1. self-assigned this
    on Aug 31, 2026
  2. changed the title [-]Implement rate limiting on authentication endpoints[/-] [+]Add stricter per-route limits and challenge-griefing protection on /auth/challenge and /auth/verify[/+] on Sep 21, 2026
  3. meshackyaro commented on Sep 21, 2026

    @meshackyaro
    ContributorAuthor

    Retitled/rescoped: already delivered in #37, #168 and #208; remaining here: global IP/wallet rate limiting exists, but /auth/* has no stricter limits, challenge replacement allows login griefing, and 429s lack headers/logs.

  4. removed their assignment
    on Sep 26, 2026
  5. Venrable18 commented on Sep 26, 2026

    @Venrable18

    @Venrable18 has applied to work on this issue as part of the Stellar Wave Program's 9th wave.

    Good day maintainer..

I’m a full-stack and test integration developer…. 

Please assign this task to me…


    ℹ️ Repo Maintainers: To accept this application, review their application or assign @Venrable18 to this issue.

  6. 0xMegie commented on Sep 26, 2026

    @0xMegie
    Contributor

    @0xMegie has applied to work on this issue as part of the Stellar Wave Program's 9th wave.

    Lets work sir... I want to take this..

    ℹ️ Repo Maintainers: To accept this application, review their application or assign @0xMegie to this issue.

  7. drips-wave commented on Sep 26, 2026

    @drips-wave

    Congratulations, @0xMegie! 🎉 Your application was accepted by the repo's maintainers, and the issue is due on September 30, 2026.

    🧑‍💻 @0xMegie: Please resolve the issue such that the repo's maintainers have enough time to review your contribution before the due date. You'll earn Points for completing the issue on-time, which will make you eligible for a share of the Stellar Wave Program's reward pool.

    Warning

    When opening a PR, please link it to this issue to ensure it gets tracked accurately. Points are awarded when this issue is marked as completed by the maintainer.

    🤠 Repo maintainers: Please keep an eye on the contributor's progress and review their work before the due date. You can manage this issue, including adjusting its complexity and points, here.

    🌊 Happy Wave 🌊

  8. grantfox-oss commented on Oct 18, 2026

    @grantfox-oss

    🎉 This issue has been marked as completed on GrantFox!

    @0xMegie's PR #774 was approved and merged by @meshackyaro.

    🏆 @0xMegie: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (532 total points). Track your full progress on GrantFox.

    👏 Great work, @0xMegie! Keep contributing to trustflow-protocol.

  9. drips-wave commented on Oct 18, 2026

    @drips-wave

    This issue has been completed by @0xMegie as part of the Stellar Wave Program's 10th Wave 🥳

    😎 @0xMegie: You earned 200 Points for completing this issue! Once the Wave's rewards are finalized, you'll be eligible for a percentage of the Wave's reward pool based on the percentage of total points you've earned. Learn more here. You can also Leave a review to share your experience working on this issue.

    🧑‍💻 Repo maintainers: How'd the contributor do? Leave a review to share your experience working with them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions