Unit
crates/cli/src/meta/types/authoring/v2.rs — AuthoringMetaV2::fetch_for_contract (AMT group g3-graphql-query-processing).
Intent oracle
IDescribedByMetaV1::describedByMetaV1() returns the hash identifying the contract's authoring meta; the metaboard subgraph is queried by that hash (get_metabytes_by_hash). The hash is the binding between the on-chain claim and the off-chain bytes — RainMetaDocumentV1Item::hash implements exactly this keccak256 binding elsewhere in the crate.
Violated property
The bytes returned by the subgraph are cbor-decoded and converted without ever being hashed:
let metas = subgraph_client.get_metabytes_by_hash(&metahash).await...?;
let meta = RainMetaDocumentV1Item::cbor_decode(metas[0].as_slice())...?[0].clone().try_into()...?;
A metaboard endpoint (or a compromised/buggy indexer behind it) can serve arbitrary words for any hash and the fetch succeeds. Additionally only metas[0] is consulted; further entries under the same hash are ignored without any consistency check.
Verified repro
meta::types::authoring::v2::tests::test_fetch_for_contract_success (added in the AMT coverage PR) mocks describedByMetaV1() returning 0x1111…11 and a metaboard serving cbor bytes whose keccak256 is not that hash — the fetch returns the words without complaint.
Triage framing
The metaboard URL is caller-supplied and may be considered trusted, in which case this is by design; flagging because verifying keccak256(meta_bytes) == metahash is cheap, the crate already has the hashing primitive, and the current behaviour silently converts a content-addressed lookup into a trust-the-server lookup. Not adjudicating here.
Unit
crates/cli/src/meta/types/authoring/v2.rs—AuthoringMetaV2::fetch_for_contract(AMT group g3-graphql-query-processing).Intent oracle
IDescribedByMetaV1::describedByMetaV1()returns the hash identifying the contract's authoring meta; the metaboard subgraph is queried by that hash (get_metabytes_by_hash). The hash is the binding between the on-chain claim and the off-chain bytes —RainMetaDocumentV1Item::hashimplements exactly this keccak256 binding elsewhere in the crate.Violated property
The bytes returned by the subgraph are cbor-decoded and converted without ever being hashed:
A metaboard endpoint (or a compromised/buggy indexer behind it) can serve arbitrary words for any hash and the fetch succeeds. Additionally only
metas[0]is consulted; further entries under the same hash are ignored without any consistency check.Verified repro
meta::types::authoring::v2::tests::test_fetch_for_contract_success(added in the AMT coverage PR) mocksdescribedByMetaV1()returning0x1111…11and a metaboard serving cbor bytes whose keccak256 is not that hash — the fetch returns the words without complaint.Triage framing
The metaboard URL is caller-supplied and may be considered trusted, in which case this is by design; flagging because verifying
keccak256(meta_bytes) == metahashis cheap, the crate already has the hashing primitive, and the current behaviour silently converts a content-addressed lookup into a trust-the-server lookup. Not adjudicating here.