From the dig-node PR#87 adversarial gate (non-blocking residual of the D1 SafeId fix): a peer-supplied identifier that fails is_canonical_hex_id logs as the fixed sentinel <non-canonical>. That is correct for security (a log an attacker can write is not evidence — see dig_ecosystem#1603), but an operator debugging a NEARLY-right id (63 hex chars, an 0x prefix, uppercase-with-a-typo) loses the 'what did they actually send' detail.
Task
Emit a BOUNDED, non-injectable shape hint alongside the sentinel — e.g. <non-canonical len=63 charset=hex> / charset=hex+prefix / charset=non-hex, computed from the raw value but never echoing it. Fixed-size output, no attacker-controlled bytes, so the forgery/amplification properties are preserved.
Applies to both serve-log paths (dig.fetchRange + dig.getAvailability) in crates/dig-node-core/src/seams/dig_peer/serve_log.rs. Add a test that the hint is emitted, bounded, and contains no bytes from the input.
Priority: Low — diagnosis nicety; the security property is already correct.
From the dig-node PR#87 adversarial gate (non-blocking residual of the D1
SafeIdfix): a peer-supplied identifier that failsis_canonical_hex_idlogs as the fixed sentinel<non-canonical>. That is correct for security (a log an attacker can write is not evidence — see dig_ecosystem#1603), but an operator debugging a NEARLY-right id (63 hex chars, an0xprefix, uppercase-with-a-typo) loses the 'what did they actually send' detail.Task
Emit a BOUNDED, non-injectable shape hint alongside the sentinel — e.g.
<non-canonical len=63 charset=hex>/charset=hex+prefix/charset=non-hex, computed from the raw value but never echoing it. Fixed-size output, no attacker-controlled bytes, so the forgery/amplification properties are preserved.Applies to both serve-log paths (
dig.fetchRange+dig.getAvailability) incrates/dig-node-core/src/seams/dig_peer/serve_log.rs. Add a test that the hint is emitted, bounded, and contains no bytes from the input.Priority: Low — diagnosis nicety; the security property is already correct.