feat: enforce invoiceRateLimit on 402 challenge path (4.7.0)#35
Merged
Conversation
Adds a call-count assertion to the invoiceRateLimit suite: after maxPendingPerIp requests, the (N+1)th is blocked with 429 and backend.createInvoice call count remains exactly N.
…ing 402 Express, Web-Standard, and Hono adapters now use result.status from the discriminated union instead of a literal 402, so rate-limited IPs receive HTTP 429 as the engine intends. Adds a sibling 429 test in each adapter test file to cover the invoice-rate-limit challenge path.
- CHANGELOG: note TollBoothResult challenge status union widened to include 429 - CHANGELOG: clarify INVOICE_MAX_AGE_MS default is 1 hour in the example; library default remains 24 hours - CLAUDE.md: same INVOICE_MAX_AGE_MS scope clarification in env-vars table
Add a sentence to the production checklist noting that invoiceRateLimit.maxPendingPerIp caps both /create-invoice and the inline 402 challenge, returning 429 with Retry-After when exceeded.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
invoiceRateLimit.maxPendingPerIpcap previously only fired in the explicitPOST /create-invoicehandler. Any priced endpoint could still mint unbounded unpaid invoices via the 402 challenge code path — confirmed in the wild: a single IP hammered/routeonrouting.trotters.ccand created 253 unpaid invoices in 35 seconds.This branch extends the cap to the 402 path, hoists the check before
backend.createInvoiceis called (so rate-limited IPs do not even touch the LSP), and exposesINVOICE_MAX_AGE_MSon the valhalla-proxy example for faster auto-prune.Changes
TollBoothCoreConfiggainsinvoiceRateLimit?: { maxPendingPerIp: number }— forwarded fromBoothConfig.issueChallenge()short-circuits with HTTP 429 +Retry-After: 3600whenpendingInvoiceCount(ipHash) >= maxPendingPerIp. Same error string as the existing/create-invoice429.result.statusinstead of hard-coding 402, so the 429 actually reaches the wire.TollBoothResultchallengevariant:status: 401 | 402 | 429.examples/valhalla-proxy/server.tsreadsINVOICE_MAX_AGE_MS(default 1h in the example; library default unchanged at 24h).Test plan
npm run typecheck— cleannpm run build— cleannpm test— 860 passing, 32 skipped, 0 failing