fix(gateway): detect C1 control characters in config lookup path sanitizer#103402
fix(gateway): detect C1 control characters in config lookup path sanitizer#103402lsr911 wants to merge 2 commits into
Conversation
Same C1 gap pattern as openclaw#103274. Add full C1 range (0x80-0x9f). Co-Authored-By: Claude <[email protected]>
|
Codex review: needs real behavior proof before merge. Reviewed July 11, 2026, 4:39 AM ET / 08:39 UTC. Summary PR surface: Source 0, Tests +21. Total +21 across 2 files. Reproducibility: yes. at source and dependency-contract level with high confidence: current code passes C1 characters through the helper, and a real Node child-process failure confirms that its error message can echo the same raw path into the warning suffix. Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Sanitize every untrusted dynamic field in the complete gateway warning, preserve the bounded and UTF-16-safe path rendering, add an exec-style regression that echoes the U+009B-bearing path, and attach redacted real warning output before merge. Do we have a high-confidence way to reproduce the issue? Yes at source and dependency-contract level with high confidence: current code passes C1 characters through the helper, and a real Node child-process failure confirms that its error message can echo the same raw path into the warning suffix. Is this the best way to solve the issue? No, not as submitted. Extending the path predicate is correct, but the full warning must also sanitize child-process error text that can repeat the path, and the maintained test must pass repository lint. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 36e54a883038. Label changesLabel justifications:
Evidence reviewedPR surface: Source 0, Tests +21. Total +21 across 2 files. View PR surface stats
Security concerns:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (1 earlier review cycle)
|
Add a regression asserting that a config path carrying a C1 byte (U+009B CSI) is replaced with '?' by sanitizeLookupPathForLog before it reaches the config.openFile warning log, and that no raw C1 byte survives. Assertion is scoped to the sanitized filename so it is OS-path-prefix independent. Signed-off-by: lsr911 <[email protected]>
|
Superseded by #104362 — a single sink-wide C1 (0x80–0x9f) pass that folds this sink's fix in with a valid U+009B regression, alongside an audit of every other control-character sink (already-covered / deferred / out-of-scope). This consolidates the isolated C1 PRs per the direction on #103226. Closing in favor of the consolidated review. |
…g sinks Terminal-control sanitizers guard untrusted text before it reaches a terminal or log (CWE-117). The canonical range is C0 (0x00-0x1f), DEL (0x7f), and C1 (0x80-0x9f) - the range already used by the shared sanitizeForLog and by renderTerminalBufferText (openclaw#103274). C1 includes the 8-bit CSI introducer U+009B. Deliberate sink-wide pass: closes the C1 gap in twelve terminal/log output sinks, each keeping its own strip/escape/replace/truncate/reject action and gaining a focused valid-U+009B regression test. The PR body audits every other control-char sink (already-covered, deferred, or out-of-scope). Consolidates the isolated PRs openclaw#103379 openclaw#103380 openclaw#103381 openclaw#103382 openclaw#103383 openclaw#103402 Signed-off-by: lsr911 <[email protected]> openclaw#103405 and re-lands the sanitizeForConsole fix from openclaw#103226 cleanly.
What Problem This Solves
sanitizeLookupPathForLog()insrc/gateway/server-methods/config.tsreplaces control characters in a config path with?before the path is embedded in the gateway warning logs (config.schema.lookup produced invalid payload for ...andconfig.openFile failed path=...). It only replaced the C0 range (0x00-0x1f) and DEL (0x7f), not the C1 control range (0x80-0x9f), which includes the CSI introducer U+009B — an alternative ANSI escape prefix equivalent toESC [. A C1 byte in the path therefore passed unchanged into both warning-log callers.Change
Extend the replacement predicate to also cover 0x80-0x9f:
Testing / Proof
Added a regression to the existing
config.openFilesuite insrc/gateway/server-methods/config.test.ts. It drives the realconfig.openFilehandler with a config path containing U+009B, forces an open failure, and asserts the emittedlogGateway.warnmessage replaces the C1 byte with?(cfg?.json) and contains no raw C1 byte. The assertion is scoped to the sanitized filename so it is independent of the OS-specific path prefix.The new
replaces C1 control characters in the logged failed config pathtest passes (passed count rises from 12 → 14, i.e. +1 in each of the two gateway vitest projects).