Skip to content

DoS: getModuleInfo is O(whole module) CPU per ~100-byte peer request, uncached and unrate-limited #109

Description

@MichaelTaylor3d

From the dig-node PR#108 adversarial gate (MEDIUM, non-blocking there):

describe_module (module_serve.rs:76-87) does fs::read of the ENTIRE module + SHA-256 of the whole blob + SHA-256 of EVERY chunk, per call. read_module_window reads the entire module for a ≤4 MiB window. There is no descriptor cache and no per-peer rate limit; stream_module_range is paced by the outbound limiter (bytes OUT) but the work is not. So a peer can spam ~100-byte dig.getModuleInfo frames and buy a full-file read + full hashing each time — a large asymmetry.

Mitigating context: the pre-existing local serve already fs::reads the whole module per request (lib.rs:1025/1056), so the read is the established pattern; the genuinely NEW cost is the per-request full hashing.

Task

  • Memoize the descriptor keyed by (path, mtime, len) — cheap and removes the hashing asymmetry entirely.
  • Consider metering descriptor requests through the FCFS limiter (work, not just bytes) or a small per-peer request budget.
  • Tests: two descriptor requests for an unchanged module hash the file once; a modified module invalidates the memo.

Priority: Medium.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions