feat(security): webhook secret + per-user rate limit + 429 retry#25
Merged
feat(security): webhook secret + per-user rate limit + 429 retry#25
Conversation
…etry
Audit (2026-05-01) flagged three skin-deep bot patterns. All three now
land together because they share the per-message handler call site.
Webhook secret token (config + index)
- WEBHOOK_SECRET env var. Required when WEBHOOK_URL is set; config.js
rejects boot-time when one is set without the other.
- .env.example documents the openssl rand -hex 32 generation.
- bot.api.setWebhook() registers it with Telegram, webhookCallback()
enforces the X-Telegram-Bot-Api-Secret-Token header. Forged updates
from anyone who learns the URL are now rejected at the HTTP layer.
Per-user rate limit (handlers/echo.js)
- Wires the existing src/lib/rate-limiter.js into the message handler
(10 msg / minute / user). Limited users are silently dropped — we
do NOT reply, since the reply itself burns Telegram outbound budget
and amplifies the abuse.
- Comment notes the in-memory limitation for sharded deployments.
Telegram 429 RetryAfter (lib/safe-reply.js)
- New safeReply() helper centralises ctx.reply error handling: catches
GrammyError 429, sleeps the server-suggested seconds, retries once,
and gives up gracefully. Other GrammyError / HttpError swallowed
with a structured log line.
- echo.js now goes through safeReply() instead of a bare try/catch.
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.
From the 2026-05-01 audit (P1.8). Three findings landed together because they share the message-handler call path.
Changes
WEBHOOK_SECRETenv var, required whenWEBHOOK_URLis set.bot.api.setWebhook({ secret_token })+webhookCallback({ secretToken })make grammy verify theX-Telegram-Bot-Api-Secret-Tokenheader on every incoming request.src/lib/rate-limiter.jsintohandlers/echo.js(10 msg/min/user). Limited users are silently dropped (replying would burn outbound budget).lib/safe-reply.jscatchesGrammyError429, sleeps the suggested seconds, retries once, swallows other API/HTTP errors with structured logs.Test plan