Skip to content

[security] No length validation on peer-supplied names enables DoS via oversized strings #189

@intendednull

Description

@intendednull

Problem

The state machine (crates/state/src/materialize.rs) applies CreateChannel, RenameChannel, RenameServer, and SetProfile events without enforcing any length limit on the name/display_name fields. A malicious peer can broadcast events with megabyte-sized strings that propagate to all peers and are:

  • Rendered as text in the channel sidebar (crates/web/src/components/channel_sidebar.rs:724)
  • Used as title attributes on hover
  • Rendered in the member list (crates/web/src/components/member_list.rs:179, 300)
  • Interpolated into confirm dialog messages (format!("Delete #{}?", name))
  • Stored in the event DAG permanently (replayed on every new peer join)

This is a denial-of-service vector: oversized names cause excessive memory usage, sluggish rendering, and layout breakage on all peers in the server.

Severity

MEDIUM — DoS. A single malicious peer with ManageChannels permission can degrade the UI for all peers. SetProfile requires no special permission (any member can set their display name).

Fix

Add length validation in apply_event in crates/state/src/materialize.rs for the following event kinds:

// Reject events where names exceed reasonable limits
EventKind::CreateChannel { ref name, .. } |
EventKind::RenameChannel { ref name, .. } => {
    if name.len() > 100 {
        return ApplyResult::Rejected("channel name exceeds 100 chars".into());
    }
}
EventKind::RenameServer { ref name } => {
    if name.len() > 100 {
        return ApplyResult::Rejected("server name exceeds 100 chars".into());
    }
}
EventKind::SetProfile { ref display_name, .. } => {
    if display_name.as_ref().map_or(false, |n| n.len() > 64) {
        return ApplyResult::Rejected("display name exceeds 64 chars".into());
    }
}

Also add UI-layer truncation as defense-in-depth (CSS text-overflow: ellipsis + max-width on name elements).

Locations

  • crates/state/src/materialize.rs:307-322 — CreateChannel (no length check)
  • crates/state/src/materialize.rs:474-485 — SetProfile (no length check)
  • crates/web/src/components/channel_sidebar.rs — renders names without truncation
  • crates/web/src/components/member_list.rs:179, 300 — renders display names without truncation

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions