fix(cli): guard CSV cells against formula injection via jsonguard - #8
fix(cli): guard CSV cells against formula injection via jsonguard#8h4x0r wants to merge 2 commits into
Conversation
sqlite4n6's private csv_escape applies RFC 4180 quoting only; it never
neutralizes a spreadsheet formula lead-in. Every cell it renders comes out
of the evidence file — carved column values, fragment cells, anomaly
notes — and is therefore attacker-controlled.
A carved value beginning with =, +, - or @ reaches the examiner's
spreadsheet as a live formula.
These two tests fail on the current implementation:
unguarded formula cell "=cmd|'/c calc'!A1" in row:
3,128,1,freelist-page,0.90,=cmd|'/c calc'!A1
unguarded formula cell "=cmd|'/c calc'!A1" in row:
LOW,SQLITE-FREELIST-NONEMPTY,free_pages=4,=cmd|'/c calc'!A1
RED commit: tests only, no implementation change.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replace the private csv_escape body with the fleet's shared jsonguard::csv_field, which applies RFC 4180 quoting *and* neutralizes a leading =, +, - or @ with an apostrophe. It also closes two gaps the local escaper had: a lone CR never triggered quoting, and bidi-override and C0 control characters passed straight through into the cell. Every value on this path is carved out of the evidence file — column values, fragment cells, anomaly notes — so all of it is attacker controlled. Adopting the shared sanitizer rather than re-implementing the guard keeps one definition of "safe cell" across the fleet. The jsonl and xlsx views are untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
The defect
cli/src/lib.rsrendered every CSV cell through a privatecsv_escapethat applied RFC 4180 quoting and nothing else. Its 26 call sites feed it values read straight out of the evidence file — carved column values, fragment cells, snapshot labels, anomaly notes. A stored value beginning with=,+,-or@therefore reached the examiner's spreadsheet as a live formula.Two smaller gaps in the same function: a lone
\rnever triggered quoting (the predicate tested,,"and\nonly), and bidi-override and C0 control characters passed straight through into the cell.The fix
Adopt
jsonguard::csv_field— the fleet's shared sanitizer — instead of re-implementing the guard.jsonlandxlsxoutput are untouched.Commits
RED
c70d3f5— tests asserting no carve-CSV or audit-CSV cell begins with a formula lead-in. Confirmed failing before the fix:GREEN
a9f9597— migrate tojsonguard::csv_field; add thejsonguard = "0.2"workspace dependency.Gate
cargo build,cargo test(542 tests, 70 suites),cargo clippy --all-targets -- -D warnings,cargo fmt --check— all clean.🤖 Generated with Claude Code