docs(ledger): file CF-003 — wire-path publish_schema compile failure is fail-open
Found while fixing alkhttp's HTTP-side instance (review-001-publish-schema-validation-robust): the identical warn-and-skip pattern exists at src/protocol/dispatch.rs:352-366 — a compile failure of a Pub op's publish_schema proceeds with validator: None, so arbitrary unvalidated JSON reaches the sink handler over the wire. Suggested direction: fail-closed + per- registration validator cache (worked shape in alkhttp 1572a9d, src/gateway/schema_cache.rs) + registration-time schema compilation. Single compile site verified (both pump arms consume the one InFlightSink.publish_validator).
This commit is contained in:
1 parent
84fe94c4d7
commit
1f08f1e385
1 file changed
+37
@@ -11,6 +11,43 @@ Format: date | found-in (alkhttp context) | severity | status.
|
||||
|
||||
## Open
|
||||
|
||||
### CF-003 — `publish_schema` compile failure is fail-open on the wire dispatch path (2026-08-30)
|
||||
|
||||
- **Found in:** alkhttp Review 001 post-remediation task
|
||||
`review-001-publish-schema-validation-robust` (the GW-01/#1 follow-up
|
||||
work). While fixing alkhttp's HTTP-side instance of the pattern, the
|
||||
identical instance was verified on the wire dispatch path:
|
||||
`src/protocol/dispatch.rs:352-366` (`Dispatcher::dispatch`,
|
||||
`OperationType::Pub` arm) — when a Pub op's `publish_schema` fails to
|
||||
**compile** (`jsonschema::options().build(&schema)` errors, e.g. a
|
||||
non-array `"required"`, a non-string `"type"`, an invalid `pattern`
|
||||
regex), the pump logs `warn!("publish_schema failed to compile;
|
||||
chunks will not be validated")` and proceeds with `validator: None`.
|
||||
- **Impact:** silent unvalidated ingest, per-request. A Pub op (local
|
||||
registration or remote import) whose schema is un-compilable by the
|
||||
pinned jsonschema dialect silently receives arbitrary JSON over the
|
||||
wire that the registration *declares* validated — the handler's
|
||||
schema guarantee is transport-dependent and quietly false. One broken
|
||||
schema in the registry turns that op into an unvalidated ingest path
|
||||
with only a warn log as the tell. (Per-request recompile cost is the
|
||||
secondary issue; alkhttp's gateway cache eliminated both.)
|
||||
- **Suggested direction:** fail-closed — on compile failure, reject the
|
||||
chunk (or abort the sink dispatch) with `INTERNAL`-class
|
||||
`CallError` naming the compile failure in the log only (untrusted
|
||||
schema text off the wire), never a silent skip; cache the compiled
|
||||
validator per registration (hot-reload by schema-value comparison;
|
||||
see alkhttp's `src/gateway/schema_cache.rs` for the worked shape).
|
||||
Complementary hygiene: reject un-compilable `publish_schema` values
|
||||
at **registration time** (`OperationRegistry::register` observing
|
||||
`spec.publish_schema`, or `with_publish_schema` validating eagerly)
|
||||
so the failure never reaches traffic.
|
||||
- **alkhttp side:** fixed in alkhttp `1572a9d` (gateway cache + lazy
|
||||
resolution + stream-terminal fail-closed). The wire path is out of
|
||||
this crate's scope (AGENTS.md: no forking alkcall types; the pump is
|
||||
alkcall-internal), so the same invariant currently holds only on the
|
||||
HTTP path.
|
||||
- **Status:** open — no alkcall change made.
|
||||
|
||||
### CF-002 — demux `TooLarge` skip allocates the full peer-declared length up front (up to ~4 GiB from an 8-byte header) (2026-08-30)
|
||||
|
||||
- **Found in:** alkhttp Review 001, finding WS-12 (cross-crate;
|
||||
|
||||
Reference in new issue
Block a user