Skip to content

Optional max read size on streaming CAR decode #185

Description

@tabcat

Decoding a CAR from a streaming source (CarBlockIterator.fromIterable / fromStream, CarReader.fromIterable) reads a varint length, then buffers that many bytes into one contiguous allocation via reader.exactly(length) before yielding anything. This happens for the header, each block section, and each CID multihash, and none of those lengths is bounded, so a malicious CAR can declare a huge length and force a near-arbitrary allocation. The caller can't prevent it: a block is only visible once fully materialized, so a downstream size check runs too late. (The in-memory CarReader.fromBytes path is unaffected; it slices an already-bounded buffer.)

Proposal: an opt-in cap, off by default so nothing changes for existing callers, on any single contiguous read, which covers all three cases in one place:

CarBlockIterator.fromIterable(source, { maxReadLength })

It would throw right after decoding a length varint larger than the cap, before reader.exactly(length) reads the section, so an oversized section is rejected from its length prefix with none of its body buffered.

Happy to open a PR (we hit this decoding CARs from untrusted peers), just let me know your preferred name/shape.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions