Skip to content

Critical security vulnerabilities in ping messenger #1

@InvidiaCaeca

Description

@InvidiaCaeca

Summary

Current version of the ping messenger has multiple high/critical security gaps.
Impact is not limited to one attacker type: risks exist for active relay/network attackers, malicious peers, passive observers, and local/supply-chain compromise.

Baseline trust assumption (expected for Nostr/public relays)

Relays are transport infrastructure, not trusted security authorities.
In normal Nostr usage, clients should assume relay-delivered data can be malicious, incomplete, replayed, or modified in transit and must enforce authenticity/integrity checks locally.

This project’s default setup already targets public relays (upstream_ping/README.md:49, ping.py:278-287), so strict client-side verification is not an optional hardening feature; it is a baseline requirement.

Given this default model, relay input must be treated as untrusted and verified client-side, and this is expected across any app making these big claims regardless of relay trust.

Threat models affected

  • Active relay/network influence: forged events, key substitution, malformed-frame DoS.
  • Malicious peer behavior: identity confusion and key poisoning paths.
  • Passive relay observation: traffic/relationship metadata correlation.
  • Local/supply-chain attacker: although quite rare, addon execution and artifact trust risks still remain.

Findings

  1. Critical: inbound authenticity is not enforced before handling
  • Receive path dispatches events without mandatory event.id recompute + Schnorr verification.
  • schnorr_verify exists but is not used on inbound processing (ping.py:211).
  • Direct dispatch from relay frame to handlers (ping.py:4231-4233).
  1. Critical: no authenticated binding between Nostr identity and X25519 encryption key
  • Incoming content can overwrite peer encryption keys (ping.py:4368-4369, 4453-4455, 4485-4488).
  • Decrypt logic trusts payload-supplied sender key material (ping.py:2833, 3241).
  • Enables key-substitution / MITM-style outcomes.
  1. High: malformed input can terminate message processing (DoS)
  • Listener path lacks top-level exception containment around event handling (ping.py:4211-4222).
  • Unvalidated assumptions on frame/event shape (ping.py:4231-4233, 4263-4265, 4507, 4566).
  • Reproduced crash conditions include non-dict EVENT payload, unhashable event.id, and event.tags=None.
  1. High: metadata exposure remains significant
  • Relay-visible routing tags (r/p) expose relationship/linkage (ping.py:4003-4004).
  • Legacy discovery broadcasts stable identifiers (username, ping_id, encryption_pubkey) (ping.py:3886-3893, 3910-3915).
  • Conflicts with “No metadata” wording (upstream_ping/README.md:44).
  1. Medium: addon trust surface is weak
  • Addons are auto-loaded from multiple local paths including CWD (ping.py:513, load at 5292).
  • Official addons are downloaded without artifact signature verification (ping.py:2331-2364).
  • Core updater verifies minisign, but addon artifacts do not (ping.py:2383-2392).
  1. Medium: replay/freshness controls are weak across sessions
  • Replay/dedupe state is in-memory and reset on join/restart (ping.py:3720, 3793).
  • Dedupe relies on unverified event.id values (ping.py:4263-4265).
  1. Medium: forward secrecy is limited
  • Message encryption relies on long-lived X25519 identity keys and static ECDH-derived keys (ping.py:2705, 2813-2837, 3203-3214).
  • Ephemeral Nostr pubkeys help unlinkability but do not provide full ratcheting PCS/FS semantics.

Passive capture summary (read-only)

  • Relevant Ping events: 4124
  • Unique pubkeys: 23
  • Unique usernames: 17
  • Unique room tags (r): 12
  • Unique recipient tags (p): 17
  • Unique sender->recipient pairs: 35
  • Duplicate event IDs seen across multiple relays: 727 / 1016 (71.56%)
  • metadata-bearing events: 3919 / 4124 (95.03%)
  • Events with visible r tags: 4057 / 4124 (98.38%)

Passive capture responsible disclosure note

  • Analysis was passive listening of publicly accessible relays.
  • No unauthorized room access, credential brute-forcing, payload decryption bypass, or exploit deployment was performed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions