Skip to content

audit F14 [robustness]: EventKind::UpdateProfile.display_name has no cap during apply (sibling fields use truncate_chars) #614

@intendednull

Description

@intendednull

File: crates/state/src/materialize.rs:601
Severity: robustness (availability/DoS)
Obvious? yes

In apply_mutation(UpdateProfile), every other field (pronouns, bio, tagline, crest_color, pinned.body, elsewhere, since) uses truncate_chars(s, PROFILE_CAP_*) to silently truncate over-long input. The sibling display_name field does entry.display_name = name.clone() with NO cap and NO truncate — the same field that SetProfile rejects above 64 chars (line 558). A member can broadcast UpdateProfile { display_name: Some("a".repeat(10_000_000)) } and every receiver materialises the multi-MB string into state.profiles[author].display_name AND into state.members[author].display_name. Worse, the event still passes EventDag::insert (no payload cap — see F11), so the megastring is permanently retained in the DAG.

Fix: apply the same display_name.chars().count() > 64 rejection in the UpdateProfile branch as in SetProfile, and add a per-field byte cap in EventDag::insert so the bloat never reaches the heap.


Filed by /general-audit @ 88498a5 (2026-05-04). master: #600.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions