Neutralize CSV formula injection in recording output - #175
Conversation
Code Review: CSV Formula Injection NeutralizationOverviewThis PR fixes a real security vulnerability (CWE-1236) in the CSV recording output. OPC UA server-supplied fields (DisplayName, NodeId, Value, Status) are passed through a new The approach is correct and the logic is sound. A few things worth discussing: Correctness
Combined neutralize + quote test is correct — Numeric exception overfits slightly — Missing trigger characterThe OWASP CSV Injection guidance and common spreadsheet behaviour also list Test coverage gapsThe four new tests cover the most important cases. A few triggers go untested:
These are not blocking issues for merging, but if you're building a regression suite the missing trigger chars are the easier wins. Minor nitIn Summary
This is a clean, well-reasoned security fix. The numeric carve-out is the right call and the code comment explaining it is valuable. Happy to approve once PR #170 lands and this retargets to |
DisplayName, NodeId, Value and Status originate from the OPC UA server,
which is potentially untrusted on a plant network. EscapeCsvField was
RFC 4180-correct but wrote fields beginning with '=', '+', '-', '@',
tab, or CR verbatim, so a DisplayName like =cmd|'/C calc'!A0 executed
as a formula when the CSV was opened in Excel/LibreOffice.
Such fields are now prefixed with a single quote ('), which spreadsheets
interpret as "treat as text". Exception: fields that parse as a number
under InvariantCulture (double.TryParse, NumberStyles.Float) are left
untouched - recorded values are routinely negative numbers (-12.5) and
prefixing them would corrupt the data column for downstream tools.
Neutralization runs before RFC 4180 quoting and applies to every
server-supplied field; the timestamp is generated locally in a fixed
format and the header line is constant, so neither needs it.
Tests: formula DisplayName neutralized, -12.5 value untouched,
+SomeTag neutralized, and combined neutralization + RFC 4180 quoting.
https://claude.ai/code/session_012Vopnd9vWkzELveHRgZhie
8045052 to
e9ea5f8
Compare
Code Review — PR #175: Neutralize CSV formula injection in recording output
OverviewGood targeted fix for CWE-1236. The Positives
Issues / Suggestions1.
|
Summary
Neutralizes CSV formula injection (CWE-1236) in the recording output, from the v1.0 follow-up review (
docs/V1-REVIEW-FOLLOWUP.md, low list).EscapeCsvFieldnow runs the field through aNeutralizeFormulaInjectionpass before the RFC 4180 quoting decision: fields starting with=,+,-,@, tab, or CR get a leading'prefix, so a server-supplied DisplayName like=cmd|'/C calc'!A0no longer executes as a formula when the CSV is opened in Excel/LibreOffice. DisplayName, NodeId, Value and Status all flow through it; the timestamp is locally generated in a fixed format and the header is constant.-12.5), and prefixing them would corrupt the data column for downstream tools. Documented in a comment.Test plan
dotnet build Opcilloscope.sln -c Release— 0 warnings, 0 errors+SomeTagneutralized, combined neutralize+quote case)Part of the v1 follow-up punch list (
docs/V1-REVIEW-FOLLOWUP.md, CSV formula injection low).https://claude.ai/code/session_012Vopnd9vWkzELveHRgZhie
Generated by Claude Code