Skip to content

fix(security): harden bot runtime surface (sec-bot-01..09)#44

Open
Abdulkhalek-1 wants to merge 2 commits intomainfrom
fix/security-bot-2026-04-07
Open

fix(security): harden bot runtime surface (sec-bot-01..09)#44
Abdulkhalek-1 wants to merge 2 commits intomainfrom
fix/security-bot-2026-04-07

Conversation

@Abdulkhalek-1
Copy link
Copy Markdown
Collaborator

Summary

Implements 9 security hardening plans covering the bot process.

# Plan Fix
01 queryraw-guildid-verification Regression tests pinning $queryRaw parameterized safety
02 webhook-header-allowlist Replace header denylist with strict allowlist
03 sanitize-welcome-canvas-names Strip bidi/zero-width/control chars before canvas render
04 action-rule-name-whitelist Restrict rule names to `[a-zA-Z0-9 _-]{1,50}`
05 resolvetemplate-literal-only-verification Fix escape lookbehind in resolveTemplate + adversarial tests
06 emoji-validation-addreaction Validate emoji shape before `message.react()`
07 autorole-toctou-handling Classify auto-role failures by Discord error code
08 levelup-mass-mention-prevention Restrict level-up mentions to leveling user only
09 warn-checkbotpermissions Add bot `ManageMessages` check to /warn

Notable

sec-bot-05 was meant to be verification-only but the regression tests exposed a real bug: the zero-width escape relied on `String.prototype.includes`, which still matched `{user.id}` even when preceded by `\u200B`. Fixed by replacing the includes-based substitution with a regex using a negative lookbehind for the sentinel. User-controlled values now genuinely cannot smuggle core variables into the second resolver pass.

Changes

  • Modified: `registry.ts`, `guildMemberAdd.ts`, `messageCreate.ts`, `actions.ts`, `warn.ts`, `persistence.ts`, `constants.ts`, `templateEngine.ts`, `welcome/image/index.ts`
  • New: `welcome/image/sanitize.ts`
  • Tests: 8 new test files + warn.test.ts update

Test plan

  • `pnpm --filter @fluxcore/bot typecheck` — clean
  • `pnpm --filter @fluxcore/bot test` — 349 pass / 16 pre-existing baseline failures (no new regressions)
  • `pnpm --filter @fluxcore/systems test` — 234/234 green
  • Manual smoke test of welcome render with hostile username
  • Manual smoke test of /warn without bot ManageMessages
  • Manual smoke test of action rule creation with hostile name

🤖 Generated with Claude Code

Implements 9 security hardening plans covering the bot process:

- sec-bot-01: regression tests pinning $queryRaw parameterized safety
- sec-bot-02: webhook headers -> strict allowlist (was denylist)
- sec-bot-03: sanitize usernames/guild name before welcome canvas render
  (strip bidi overrides, zero-width chars, control chars)
- sec-bot-04: restrict action rule names to [a-zA-Z0-9 _-]{1,50}
- sec-bot-05: templateEngine - fix escape lookbehind so escaped user
  content can no longer smuggle core variables into the second pass,
  plus adversarial regression tests
- sec-bot-06: validate emoji against Unicode/custom-emoji form before
  message.react()
- sec-bot-07: classify auto-role assignment failures by Discord API
  error code (50013/10011 warn, others error)
- sec-bot-08: level-up announcements restrict mentions to the leveling
  user only via allowedMentions config
- sec-bot-09: add checkBotPermissions for ManageMessages to /warn

Adds sanitizeDisplayName helper in packages/systems/welcome.
Bot test suite: 349 pass / 16 pre-existing baseline failures (no new
regressions). Systems test suite: 234/234 green.
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.

1 participant