fix(telegram): restore command auth boundary and scope command registration

Restrict command handling to TELEGRAM_CHAT_ID again to prevent arbitrary private chats from executing privileged bot commands. Keep reply routing, @BotName parsing, and long-message chunking while scoping setMyCommands to the configured chat only.

Made-with: Cursor
This commit is contained in:
satoshipanic
2026-03-18 08:20:32 +01:00
parent 28121298cf
commit 801293356c

View File

@@ -359,10 +359,9 @@ export class TelegramAlerter {
const msg = update.message;
if (!msg?.text) continue;
const chatType = msg.chat?.type;
const chatId = String(msg.chat?.id);
// Commands can come from private chats or the configured chat/group.
if (chatType !== 'private' && chatId !== String(this.chatId)) continue;
// Restrict command execution to the configured chat/group only.
if (chatId !== String(this.chatId)) continue;
await this._handleMessage(msg);
}
@@ -457,10 +456,8 @@ export class TelegramAlerter {
description: description.substring(0, 256),
}));
// Register globally, then force explicit private/group scopes.
await this._setMyCommands(botCommands);
await this._setMyCommands(botCommands, { type: 'all_private_chats' });
await this._setMyCommands(botCommands, { type: 'all_group_chats' });
// Register commands only for the configured chat to avoid global discovery.
await this._setMyCommands(botCommands, this._buildConfiguredChatScope());
}
async _loadBotIdentity() {
@@ -498,6 +495,14 @@ export class TelegramAlerter {
}
}
_buildConfiguredChatScope() {
const chatId = Number(this.chatId);
if (!Number.isSafeInteger(chatId)) {
throw new Error(`TELEGRAM_CHAT_ID must be a numeric chat id, got: ${this.chatId}`);
}
return { type: 'chat', chat_id: chatId };
}
_normalizeCommand(rawCommand) {
if (!rawCommand.startsWith('/')) return null;