SECURITY: display names accept bidi override characters, so a user can spoof how their name reads #144

Closed
opened 2026-09-25 23:17:34 +00:00 by kayg · 1 comment
Owner

Severity: medium (SECURITY: spoofing another user's name)

Problem

Display names accepted bidirectional format characters. An invitee who signs up as Mallory 🎭 ‮evil‬ With A Very Long Display Name Indeed is shown to everyone as "Mallory 🎭 live With A Very Long Display Name Indeed" (Settings → Admin → Users, the share dialog's people list, share notifications). /home/kayg/Developer/calternal/target/breakit/run1/settings-admin-users_320-paper.png. File names and note titles already refuse these characters; display names did not.

Repro

  1. Invite a user. Sign up with display_name = "Mallory \u202eevil\u202c" (or PATCH /api/v1/auth/me/profile).
  2. Open Settings → Admin → Users as the owner.

Expected

400 for a display name with control characters or bidi controls (U+061C, U+200E/F, U+202A–202E, U+2066–2069). ZWJ emoji and every script stay allowed.

Status

Fixed on job/breakit-fixes (calternal-auth valid_display_name, used by every user write and the passkey registration precheck; unit test display_names_refuse_bidi_and_control_characters; probe section display-names in tests/adversarial/attack2.py). Not merged. Existing names are not rewritten: an instance that already has such a name keeps it until the user edits it.

Found by the break-it sweep (#117).

**Severity:** medium (SECURITY: spoofing another user's name) ## Problem Display names accepted bidirectional format characters. An invitee who signs up as `Mallory 🎭 ‮evil‬ With A Very Long Display Name Indeed` is shown to everyone as **"Mallory 🎭 live With A Very Long Display Name Indeed"** (Settings → Admin → Users, the share dialog's people list, share notifications). `/home/kayg/Developer/calternal/target/breakit/run1/settings-admin-users_320-paper.png`. File names and note titles already refuse these characters; display names did not. ## Repro 1. Invite a user. Sign up with `display_name` = `"Mallory \u202eevil\u202c"` (or `PATCH /api/v1/auth/me/profile`). 2. Open Settings → Admin → Users as the owner. ## Expected 400 for a display name with control characters or bidi controls (U+061C, U+200E/F, U+202A–202E, U+2066–2069). ZWJ emoji and every script stay allowed. ## Status Fixed on `job/breakit-fixes` (calternal-auth `valid_display_name`, used by every user write and the passkey registration precheck; unit test `display_names_refuse_bidi_and_control_characters`; probe section `display-names` in `tests/adversarial/attack2.py`). Not merged. Existing names are not rewritten: an instance that already has such a name keeps it until the user edits it. Found by the break-it sweep (#117).
Author
Owner

Fixed in dcd6337cc (origin/dev); covered by display_names_refuse_bidi_and_control_characters and the display-names section of tests/adversarial/attack2.py.

Fixed in dcd6337cc (origin/dev); covered by `display_names_refuse_bidi_and_control_characters` and the `display-names` section of `tests/adversarial/attack2.py`.
kayg closed this issue 2026-10-03 11:55:06 +00:00
Sign in to join this conversation.
No labels
No milestone
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
kayg/calternal#144
No description provided.