Skip to content

fix: redact bot token from Telegram HTTP errors (#65) - #67

Merged
eliau2005 merged 1 commit into
mainfrom
fix/65-redact-token
Sep 13, 2026
Merged

eliau2005 merged 1 commit into
mainfrom
fix/65-redact-token

Conversation

@eliau2005

Copy link
Copy Markdown
Owner

What & why

Fixes #65.

telegram.New puts the bot token in BaseURL (https://api.telegram.org/bot<TOKEN>). When a request fails (DNS, dial, TLS, timeout, cancelled context), net/http returns a *url.Error whose message contains the full request URL. Client.call wrapped that error and the agent logged it (getUpdates, push failed, edit, …), so any network hiccup wrote the token to journald in plain text — repeatedly, since botLoop retries every 5s.

Every Bot API request goes through Client.call, so the fix lives there and covers all current and future callers without touching internal/agent:

  • redact() replaces bot<digits>:<token> with bot<redacted> via a regex (not tied to BaseURL).
  • sanitizeErr() rewrites url.Error.URL in place, so the concrete type, Timeout() and errors.Is(err, context.Canceled) keep working. If the token still shows up anywhere in the message, it returns a wrapper with the redacted text and Unwrap() pointing to the original error.
  • Applied to the NewRequestWithContext and HTTP.Do error paths. The success path doesn't change, and the regex only runs when a request fails.

Example log line after the fix:

agent: getUpdates: telegram: getUpdates: Post "https://api.telegram.org/bot<redacted>/getUpdates": dial tcp ...: connection refused

How it was tested

  • go vet ./... clean, gofmt -l . empty, go test -race ./... all green (Go 1.26).
  • New tests in internal/telegram/telegram_test.go:
    • Transport failure on every public method (SendMessage, EditMessageKB, AnswerCallback, DeleteMessages, SetMyCommands, GetUpdates): no token in %v / %+v, bot<redacted> and method name present.
    • errors.As(*url.Error) still works and its URL is clean.
    • Cancelled context: errors.Is(err, context.Canceled) still holds.
    • Client timeout: url.Error.Timeout() still true.
    • Log output captured via log.SetOutput has no token.
    • Unit tests for redact (multiple occurrences, no-op on token-free strings) and for the sanitizeErr fallback wrapper (errors.Is preserved).
  • Regression check: with the sanitizeErr calls temporarily removed, 5 of the new tests fail; with the fix restored, they pass.

Checklist

  • go test ./... passes
  • go vet ./... is clean
  • Code is gofmt-formatted
  • New behavior is covered by tests (and fixes include a regression test)
  • Docs updated where behavior, commands, config, or the security surface changed (no user-facing docs affected; field comment updated)
  • The change keeps the agent featherweight and respects the OS-abstraction boundary

Note for operators: if your agent has logged Telegram network errors before this fix, the token may already be in your journal — rotate it with @Botfather.

net/http reports transport failures as *url.Error containing the full
request URL, which embeds the bot token. The agent logs these errors, so
any network failure wrote the token to the journal in plain text.

Sanitize errors in Client.call: rewrite url.Error.URL in place (keeping
the error type, Timeout() and errors.Is/As chains intact) and fall back
to a redacting wrapper if the token still appears in the message.
@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: faff2f95-2d1f-4d41-93c7-e41fe32af323


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@eliau2005
eliau2005 merged commit b8be7b0 into main Sep 13, 2026
3 checks passed
@eliau2005
eliau2005 deleted the fix/65-redact-token branch September 13, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bot token is written to the journal in plain text whenever a Telegram HTTP request fails

1 participant