Bot posts: person-written text reaches Discord unescaped #1166

Closed
opened 2026-10-13 03:22:25 +00:00 by claude-bot · 0 comments
Collaborator

Found while building the RSVP nudge (#1158), where five automated reviews in a row found a way round each attempt to escape a session title for Discord's markdown.

On main today

  • _handle_vote_reminder sends a plain line that includes the session title with allowed_mentions(users=True): a <@id> typed into a title pings that person. (#1158 tightens this one line to the exact ids; the rest is below.)
  • The vote line also carries the title and the names of unlinked members as text: markdown and masked links [text](url) render.
  • Embeds (faces.face): descriptions and field values render markdown and masked links; titles, campaign names, recap excerpts and quest titles land there.

Who can type that text: GMs (titles, campaign names), and players where they name things (display names, characters). Reach: the campaign's own Discord channel. So the risk is a member of a campaign putting a misleading link or formatting in a bot post, not an outsider.

Approach
Escaping for Discord's parser did not converge, so prefer structure:

  • A pinging plain line carries no person-written text (as the #1158 nudge now does): mentions, fixed words, the session number, a bot-rendered time, a validated link.
  • In embeds, decide per field: person-written text only where Discord renders no links (check what titles and footers render), or shown inside a code span with backticks stripped, or dropped.
  • One table in the bot's tests listing every face, where person-written text lands in it, and the hostile strings it is tested with.

Not in 4.5.1 unless the owner says so.

Found while building the RSVP nudge (#1158), where five automated reviews in a row found a way round each attempt to escape a session title for Discord's markdown. **On main today** - `_handle_vote_reminder` sends a plain line that includes the session title with `allowed_mentions(users=True)`: a `<@id>` typed into a title pings that person. (#1158 tightens this one line to the exact ids; the rest is below.) - The vote line also carries the title and the names of unlinked members as text: markdown and masked links `[text](url)` render. - Embeds (`faces.face`): descriptions and field values render markdown and masked links; titles, campaign names, recap excerpts and quest titles land there. Who can type that text: GMs (titles, campaign names), and players where they name things (display names, characters). Reach: the campaign's own Discord channel. So the risk is a member of a campaign putting a misleading link or formatting in a bot post, not an outsider. **Approach** Escaping for Discord's parser did not converge, so prefer structure: - A pinging plain line carries no person-written text (as the #1158 nudge now does): mentions, fixed words, the session number, a bot-rendered time, a validated link. - In embeds, decide per field: person-written text only where Discord renders no links (check what titles and footers render), or shown inside a code span with backticks stripped, or dropped. - One table in the bot's tests listing every face, where person-written text lands in it, and the hostile strings it is tested with. Not in 4.5.1 unless the owner says so.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#1166
No description provided.