Skip to content

bug: session-state poisoning — FNV-1a-authenticated dictionary, unbounded tables #7

Description

@minagishl

Bug Description

SessionEncoder maintains stateful tables (keys, strings, shapes, field-enums, dictionaries, dictionary profiles, schemas). Two related problems:

  1. Dictionary integrity is FNV-1a (dictionary_payload_hash, src/protocol.rs:3811), keyed by data the attacker also supplies. FNV-1a is not a cryptographic MAC; an attacker who can write a dictionary entry can forge any payload that produces the same hash, or simply omit the integrity step entirely since both inputs are attacker-controlled. There is no authentication of the dictionary contents against any out-of-band secret.
  2. All session tables grow unbounded. There is no per-table cap on number of registered keys, strings, shapes, field-enums, dictionaries, or observations. An attacker streaming unique-per-message keys/strings against a long-lived SessionEncoder causes linear memory growth until OOM.

Steps to Reproduce

For (1):

  1. Open a connection that uses a shared SessionEncoder between peers.
  2. Send a RegisterDictionary payload, then send a normal message that references that dictionary id with content of the attacker's choosing.
  3. Receiver decodes the attacker's content as if it were authenticated.

For (2):

  1. Open a long-lived session.
  2. Stream millions of small messages each containing a unique string in String{Literal} mode (or unique map keys).
  3. Watch process RSS grow linearly.

Expected Behavior

For (1): Dictionaries should either be authenticated with a keyed MAC tied to the session, or treated as opaque advisory data that does not affect application semantics. At minimum, document the trust model so consumers understand FNV-1a is not security.

For (2): Add configurable per-table caps (max_keys, max_strings, max_shapes, max_observations, etc.) on SessionOptions, with sensible defaults. Reject Register* operations that exceed the cap.

Actual Behavior

Dictionary integrity is FNV-1a only; tables grow unboundedly.

Environment

  • Crate: recurram, session/state module

Additional Context

Severity: High — long-lived OOM (slow-burn DoS) and stateful confusion primitive.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions