Learning objectives
After reading this article you will be able to:
- Invalidate the leaked token before anyone uses it
- Find out what an attacker may have done with your bot
- Swap the token on your host and stop it leaking again
On this page
- What should you do in the first few minutes?
- How do you reset a bot token?
- What can an attacker do with the token?
- How do you tell whether someone used the token?
- How do you swap the token with little downtime?
- How do you clean the repository afterwards?
- How do you keep the token from leaking again?
- How to do this on Square Cloud
- FAQs
A bot token is the bot's password. Whoever holds it signs in to Discord or Telegram as your bot, with no username and no verification code. If it appeared in a public repository, a screenshot, a log or a chat, treat it as compromised from that moment.
The main fix takes a minute. What takes longer is finding out what was done with the token and making sure the new one does not leak the same way.
What should you do in the first few minutes?#
Follow this order. Do not start by cleaning the repository.
- Reset the token. It is the only step that makes the leaked value useless.
- Update the new token where the bot runs and restart the process.
- Audit the server or chat for actions you did not take.
- Clean the code and the Git history.
- Fix the cause so the next token does not leak.
The sooner you do step 1, the smaller the attack window. Bots scan public repositories for tokens, so do not wait.
How do you reset a bot token?#
Discord#
In the Developer Portal, open your application, go to the Bot tab and click Reset Token, then confirm. This invalidates all of the bot's old tokens, according to the discord.js guide. Copy the new value right away and store it directly in the environment variable.
After the reset the bot stays offline until you update the token where it runs. That is expected.
Telegram#
Open a chat with @BotFather and send /token. The Telegram documentation points to that command when the token is compromised or lost. Pick the bot and BotFather returns a new token. Another route is under /mybots: pick the bot, then API Token and Revoke current token. Either way, confirm right after that the old token is rejected (see below).
Will Discord or GitHub invalidate the token for you?#
Do not depend on it. GitHub has a secret scanning pattern for the Discord bot token (discord_bot_token), listed as a partner pattern with push protection support. The Telegram bot token (telegram_bot_token) is listed with no partner and no push protection. See GitHub's pattern list.
Even for Discord, the documentation does not guarantee the token is reset for you, and detection only covers GitHub repositories. A token pasted in a screenshot, a support channel or a log never goes through that filter.
What can an attacker do with the token?#
Anything the bot can do, limited by the permissions it has in each server. The discord.js guide lists the typical risk: spamming every server the bot is in, mass DMs, deleting channels, kicking or banning members and making the bot leave its servers.
So the damage depends on permissions. A bot with Administrator can do everything; a bot that only reads and replies to messages can do far less. That is a good reason to give the bot only what it needs.
Resetting the token does not undo what was already done. It also does not remove things the attacker created that do not depend on the token, such as webhooks: a webhook URL carries its own token, so it keeps working until deleted, per the webhook documentation.
How do you tell whether someone used the token?#
On Discord#
Open the server settings and check the Audit Log. Entries are kept for 45 days, and the Discord documentation says the VIEW_AUDIT_LOG permission is required to see them. Look for:
- channels, roles or invites created or deleted that you do not recognize;
- new webhooks (delete the suspicious ones);
- members banned or kicked for no reason;
- permission changes on roles.
Also check the list of servers the bot is in. If there is a server you do not know, remove the bot from it.
Confirm the old token is dead#
Test whether the leaked token is still accepted. The Discord API takes the token in the Authorization: Bot header, as the API reference describes:
OLD_TOKEN="paste-here"
curl -s -o /dev/null -w "%{http_code}\n" \
-H "Authorization: Bot $OLD_TOKEN" \
https://discord.com/api/v10/users/@me200 means the token is still valid and the reset did not take. 401 (unauthorized) is the expected result for an invalidated token. On Telegram, the equivalent test is the Bot API getMe method, which should answer 401 for the old token:
curl -s -o /dev/null -w "%{http_code}\n" "https://api.telegram.org/bot$OLD_TOKEN/getMe"After the test, clear your terminal history.
How do you swap the token with little downtime?#
The point is to have one place where the token lives. If it is scattered across several files, you will miss one.
- Read the token from an environment variable, never from a string in the code:
// index.js (discord.js v14)
import { Client, Events, GatewayIntentBits } from "discord.js";
const token = process.env.DISCORD_TOKEN;
if (!token) throw new Error("DISCORD_TOKEN is not set");
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once(Events.ClientReady, () => console.log(`Online as ${client.user.tag}`));
client.login(token);- Update the variable on your host and in the local
.env. - Restart the bot and check the log.
If the bot does not come back, see why your Discord bot goes offline: an old token forgotten in another environment (staging, CI, another machine) is a common cause.
How do you clean the repository afterwards?#
Only after the reset. GitHub's documentation says that when the leaked data is a credential, revoking or rotating it may be enough, and rewriting history is not always necessary.
First find where the token is in the history:
git log --all -S"part-of-the-token" --onelineIf a whole .env was committed, GitHub documents git-filter-repo (version 2.47 or later) with --sensitive-data-removal:
git-filter-repo --sensitive-data-removal --invert-paths --path .env
git push --force --mirror originThis changes commit hashes, removes signatures and does not delete other people's forks or clones. The full walkthrough, with the caveats, is in API key exposed on GitHub. Since the token is already reset, this cleanup is hygiene, not security.
How do you keep the token from leaking again?#
- Out of the code. An environment variable, or a
.envin.gitignorefrom the first commit. See what environment variables are and what a .env file is. - One token per environment. One Portal application for development and another for production, as the Discord bot token guide explains.
- Minimum permissions. Avoid Administrator. Request only what the bot uses.
- No tokens in screenshots, logs or ZIPs. Whoever helps you in a support server never needs your token.
- Push protection on in GitHub, and a pass through the deploy security checklist.
How to do this on Square Cloud#
On Square Cloud, steps 2 and 3 of the swap (update the value and restart) happen in the same place, without touching the code. The token lives in an application environment variable, like DISCORD_TOKEN in the example, which you edit in the dashboard, through the API, the VS Code extension or the CLI, with app env set followed by app restart. The change applies on the next restart, with no rebuild, and no other application in the same account can read that value.
To confirm the bot is back, open the real-time logs in the dashboard, the CLI, VS Code or the mobile app and look for the example's Online as ... line. If you followed the one-token-per-environment advice, each application (test and production) has its own variables, so rotating one token doesn't take the other bot down. The dashboard also imports a .env and exports the set as KEY=VALUE; keep the file out of the ZIP and the repository, so the token only exists there.
The reset itself still happens in the Discord Portal or BotFather, and auditing your server is still up to you. See how environment variables work and what the platform offers for bots.
Infrastructure
L3/L4/L7 DDoS mitigation and a WAF on every plan
FAQs
Does deleting the commit with the token fix it?
No. Git keeps history, and the token may already be copied by forks, clones and scanning bots. Only resetting the token closes the door.
Does Discord reset the token by itself when it shows up on GitHub?
Do not rely on it. GitHub has a pattern for Discord bot tokens and notifies the partner, but the documentation does not promise a reset. Reset it yourself.
What if the token leaked on Telegram?
Message @BotFather and use the /token command to generate a new one. Telegram's documentation points to that command for a compromised or lost token.
Do I need to create a new bot?
Usually not. Resetting the token keeps the same bot in the same servers. Just update the value where the bot runs and restart it.
More in Security
See all 10 articles- What is a brute force attack and how to defend against itA brute force attack tests passwords in bulk until one works. Learn the types (spraying, credential stuffing), how they work and the defenses, with code that runs.
- My app was hacked: what to do nowIf your app was hacked, contain access, rotate every secret and preserve the logs before cleaning up. See the right order, how to find the cause and how to recover.
- Security checklist for deploying a bot, site or APIA security checklist before you deploy a bot, site or API: secrets in environment variables, dependencies, HTTPS, headers, least privilege and logs.
- How to protect your app from DDoS attacksTo protect against DDoS, combine edge mitigation (CDN and WAF) with rate limiting, timeouts and caching in your app. Step-by-step guide with working code.