Skip to main content

Module json_field

Module json_field 

Source
Expand description

SerializedJsonField — typed guard for JSON-envelope construction.

Issue #178, enforcing ADR 0010 §3.

§The boundary

Every JSON envelope this server emits — HelloAck (issue #166), gRPC PayloadReply (crates/reddb-server/src/grpc/service_impl.rs), and HTTP response bodies (crates/reddb-server/src/server/handlers_*.rs) — is a structured serialization format whose delimiter (", control bytes, {/}, :) the untrusted caller can attempt to inject. The Whiz / Babeld pattern is serialize(trusted ++ untrusted) without escape: the producer emits attacker-controlled bytes verbatim and the downstream parser sees a forged field.

SerializedJsonField is the typed point of crossing for that boundary on the producer side. Caller-influenced data does not get formatted into a JSON envelope as raw bytes; it round-trips through crate::serde_json::Value first, picking up the canonical RFC-8259-compliant escape contract from crate::serde_json::Value::to_string_compact (the F-01 hotfix shipped in #181).

§Public surface

  • SerializedJsonField::tainted — wrap an untrusted, caller- influenced string. Returns a crate::serde_json::Value::String that, when serialized, will have every control byte and JSON delimiter escaped per RFC 8259 §7. Use this for error messages, user-supplied identifiers, free-form text, and anything reaching the envelope from a parser, header, or request body.
  • SerializedJsonField::typed — wrap a known-typed value that implements crate::serde_json::JsonEncode (the in-house counterpart to serde::Serialize). Returns the value’s canonical crate::serde_json::Value representation. Use this for structs and enums whose schema is owned by the server; it guarantees the round-trip even for nested string fields.

Both forms produce a crate::serde_json::Value that the rest of the envelope assembly (Map::insert, to_string_compact) consumes uniformly. A caller never hands raw bytes to the JSON emitter; everything goes through Value.

§F-05 — SQL parser error message routing

Audit finding F-05 (see docs/security/serialization-boundary-audit-2026-05-06.md) observes that SQL parser errors interpolate user-supplied SQL fragments into their Display strings via bare format!. When such an error message reaches an HTTP response body via [crate::server::transport::json_error], the F-05 fix on the JSON wire side is to route the message through SerializedJsonField::tainted before embedding it. That fix lands in this slice via the [crate::server::transport::json_error] retrofit, which now wraps every error message with the guard regardless of upstream origin. The parser-side F-05 cleanup (avoiding format! for the offending fragment in the first place) is a separate concern tracked under Lane AG / issue #184.

§Why tainted does not return an error

Unlike crate::server::header_escape_guard::HeaderEscapeGuard, which rejects CR/LF/NUL/tab outright, SerializedJsonField cannot reject anything: every Unicode string is a legal JSON string under RFC 8259 §7 once escaped. The contract is “round-trip”, not “validate”. The result is always emittable.

Structs§

SerializedJsonField
Typed guard for JSON-envelope field construction. See module docs.