Security report (responsible disclosure)
Same check-neutralization primitive on auto-trigger execution
Affected: bot.py:1377-1384 (+ author spoofing at :1375)
for ctx in ctxs:
if ctx.command:
old_checks = copy.copy(ctx.command.checks)
ctx.command.checks = [checks.has_permissions(PermissionLevel.INVALID)]
await self.invoke(ctx)
ctx.command.checks = old_checks
Owner-configured aliases execute as the bot's own identity with all per-command permission levels voided whenever a thread recipient's first message matches a keyword (regex keys compiled against user content, bot.py:1346). This turns recipient messages into execution triggers for fully-privileged canned commands.
Standalone severity is LOW-MEDIUM (creation is OWNER-gated), but it's the same design flaw reported for the thread-menu path: there is no scenario where bypassing a command's declared level is correct.
Suggested fix
Remove the check-swap pattern entirely; run privileged aliases through an explicit server-side code path that doesn't masquerade as an invoker with bypassed checks.
Security report (responsible disclosure)
Same check-neutralization primitive on auto-trigger execution
Affected:
bot.py:1377-1384(+ author spoofing at :1375)Owner-configured aliases execute as the bot's own identity with all per-command permission levels voided whenever a thread recipient's first message matches a keyword (regex keys compiled against user content,
bot.py:1346). This turns recipient messages into execution triggers for fully-privileged canned commands.Standalone severity is LOW-MEDIUM (creation is OWNER-gated), but it's the same design flaw reported for the thread-menu path: there is no scenario where bypassing a command's declared level is correct.
Suggested fix
Remove the check-swap pattern entirely; run privileged aliases through an explicit server-side code path that doesn't masquerade as an invoker with bypassed checks.