Skip to content

fetch_by_subject returns an arbitrary, unverified meta when multiple metas share a subject #215

Description

@thedavidmeister

Unit

crates/cli/src/meta/types/dotrain/source_v1.rsDotrainSourceV1::fetch_by_subject; crates/metaboard/src/types/metas.rs — the MetasBySubject query.

Intent oracle

Per IDescribedByMetaV1, metadata is content-addressed by hash and emitters are untrusted; the metaboard is append-only, so multiple metas can be emitted under the same subject by different (untrusted) senders. DotrainSourceV1 even exposes a hash() = keccak256(source). The subgraph schema exposes orderBy/orderDirection on meta_v1_s.

Violated property

fetch_by_subject takes metabytes[0] and decoded_items[0], with:

  1. No orderBy on the MetasBySubject query (#[arguments(where: { subject: $subject })] only) — so which row is "first" is indexer-implementation-defined and nondeterministic when more than one meta shares the subject.
  2. No verification that the returned DotrainSourceV1.hash() equals the requested subject.

A malicious emitter can publish an arbitrary DotrainSourceV1 under a target subject; depending on indexer ordering, fetch_by_subject(subject) may then return attacker-controlled source. The result is both nondeterministic and unverifiable.

Verified repro

With two DotrainSourceV1 metas under one subject, fetch_by_subject returns whichever row the query yields first, with no tie-break and no hash check (demonstrated by the added test test_fetch_by_subject_decodes_first_meta, which pins selection of the first row purely by position).

Triage framing

Whether the subject is intended to be the content hash (which would enable verification) and whether determinism matters for this lookup are design questions for maintainers. Filing the missing ordering + hash verification for adjudication; neutral.

Metadata

Metadata

Assignees

No one assigned

    Labels

    adversarialFound by adversarial review/mutation testingauditAudit finding; counted by the org health scan

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions