Skip to content

fix(cli): guard CSV cells against formula injection via jsonguard - #8

Draft
h4x0r wants to merge 2 commits into
mainfrom
fix/csv-formula-guard
Draft

fix(cli): guard CSV cells against formula injection via jsonguard#8
h4x0r wants to merge 2 commits into
mainfrom
fix/csv-formula-guard

Conversation

@h4x0r

@h4x0r h4x0r commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Sequencing: this PR alone does not close the CR bypass. It pins jsonguard = "0.2", which resolves to the published 0.2.4. That version guards =, +, - and @ in the first position, but not a lead-in hidden behind leading whitespace — "\r=1+1" still reaches the cell unguarded. That gap is fixed in jsonguard#5 and arrives here only once it merges and release-plz publishes 0.2.5. Merging this PR first is correct and strictly improves matters; just don't read it as closing the whole class.

The defect

cli/src/lib.rs rendered every CSV cell through a private csv_escape that 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 \r never triggered quoting (the predicate tested ,, " and \n only), 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. jsonl and xlsx output 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:

    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
    
  • GREEN a9f9597 — migrate to jsonguard::csv_field; add the jsonguard = "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

h4x0r and others added 2 commits August 2, 2026 07:57
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>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedcargo/​jsonguard@​0.2.48610097100100

View full report

@socket-security

Copy link
Copy Markdown

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.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Potentially malicious package (AI signal): cargo jsonguard is 90.0% likely malicious

Notes: This fragment is a highly suspicious/malicious spreadsheet-style payload combining (1) client-side command execution attempts via cmd/DDE constructs and (2) exfiltration of spreadsheet cell contents to an attacker-controlled domain via WEBSERVICE and IMPORTXML URL query parameters, with an additional lure link via HYPERLINK. Treat as actively dangerous when opened/evaluated in spreadsheet software.

Confidence: 0.90

Severity: 1.00

From: Cargo.lockcargo/jsonguard@0.2.4

ℹ Read more on: This package | This alert | What is AI-detected potential malware?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Given the AI system's identification of this package as malware, extreme caution is advised. It is recommended to avoid downloading or installing this package until the threat is confirmed or flagged as a false positive.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore cargo/jsonguard@0.2.4. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant