0xMiden / 0xMiden/note-transport-service

SendNote accepts arbitrary unverified blobs (no on-chain commitment / header-details binding)

Abierto
#116 0 comentarios 0 reacciones 0 asignados Ver en GitHub
enhancement production-readiness
Lenguaje dominante
Rust
Estrellas
3
Forks
10
Merge medio
2 h 23 min
PR fusionados (30 d)
4

Descripción

Severity: high.

### Summary

`SendNote` performs no validation beyond deserializing the header and enforcing a size cap. Anyone can store arbitrary bytes under any tag.

### Evidence

`crates/node/src/node/grpc/mod.rs:174-199`: the only checks are `note_size > max_note_size` and `NoteHeader::read_from_bytes(&pnote.header)`. Specifically, the server does **not**:

- verify the note is committed on-chain (no chain lookup anywhere);
- verify that `pnote.details` corresponds to the header's `NoteId` (details is stored verbatim);
- validate `after_block_num` — the proto explicitly documents it is stored verbatim and never validated (`proto/proto/miden_note_transport.proto:19-28`).

### Impact

- Storage can be filled with garbage that no recipient will ever fetch (compounds the unbounded-storage issue).
- A recipient must treat every fetched note as fully untrusted; there is no server-side guarantee that a note under a tag is real.
- Enables the header front-running / poison-note denial described in #47.

### Recommendation

Preferred direction (per design discussion — see #115): **inclusion-proof validation** — the NTL only accepts a note once its commitment is registered on-chain. Concretely, two checks together:

1. Require an inclusion proof that the note commitment exists in the node's note DB (proves the note is real and on-chain).
2. Recompute the commitment from the submitted note contents and check it equals the proven commitment (binds `details` to the commitment — this is what stops poison/front-running; the inclusion proof alone does not).

This doubles as the primary write-side anti-abuse control: because creating an on-chain note costs fees, write-flooding and storage exhaustion (#117, #118) become economically bounded, and the squatting vector (#47) closes. It introduces two surfaces to handle: the NTL gains a live dependency on a Miden node (availability/latency coupling), and the verification lookup itself is floodable — mitigate with a verified-commitment cache plus rate limiting on the verification path specifically.

Weaker fallback if inclusion-proof validation is deferred: at minimum verify `details` hash-matches the header's details commitment (cheap, no chain access) so a stored note is at least internally consistent. Service fees for the NTL are a separate, more complex alternative (payment rails).

Related: #115 (gating decision), #47 (squatting — closed by this), #117/#118 (write path largely subsumed by this), #92 (slimming the header), #44 (spam).

---
Part of #114.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.