On this page
Name the two interpreters
A CSV file has a text grammar and a consumer interpretation. RFC 4180 discusses records, commas, quotes, and line breaks; a spreadsheet application may add a formula language on top of those characters. Review both layers. A cell can be valid CSV and still be unsafe or surprising when opened by a human spreadsheet user, while a prefix added for spreadsheet safety can become unwanted data for an API or database import.
The RFC Editor, (opens in a new tab) document is a format reference, not a promise that every spreadsheet behaves the same way. Start the worksheet with the intended consumer, the expected literal value, and whether the output is human-viewed or machine-ingested. If the audience is mixed, produce separate artifacts or explicitly accept the trade-off instead of silently applying one policy.
| Boundary | Record | Unknown if |
|---|---|---|
| CSV grammar | delimiter, quote, line ending, encoding | The parser configuration is unstated |
| cell value | exact text before export | Only a displayed spreadsheet value remains |
| consumer | spreadsheet, database, API, or mixed | Audience is assumed from the extension |
| formula policy | literal, neutralized, or rejected | No owner decision exists |
| leading zeros | text preservation rule | Identifiers were cast to numbers |
| audit trail | input, transform, and output references | Only the final file is retained |
Identify formula-like starts without testing live payloads
OWASP calls out cells beginning with characters such as equals, plus, minus, or at sign as formula-injection risk in spreadsheet applications. Treat that as a classification rule for a review, not an invitation to place a live formula or a harmful payload in a real export. Use neutral synthetic strings and record the first character, intended literal meaning, and target consumer.
Do not confuse CSV quoting with neutralization. Quotes preserve field boundaries under the CSV grammar; they may not prevent a spreadsheet from recognizing a formula after it loads the cell. Conversely, a leading apostrophe or tab can alter the stored text for a machine consumer. The correct policy depends on the output contract and must be tested with the actual approved consumer version.
| Synthetic cell class | Human spreadsheet risk | Machine-import question |
|---|---|---|
| starts with equals | may be evaluated | Should the leading character remain literal? |
| starts with plus or minus | may be interpreted by some applications | Will numeric parsing change? |
| starts with at sign | may be treated as a formula marker | Is the value an email-like identifier or code? |
| quoted comma text | grammar delimiter only | Does downstream unquote once? |
| leading-zero identifier | numeric coercion risk | Must it remain text? |
| empty string or null | semantic ambiguity | Are blank and unavailable distinct? |
Choose a policy and preserve its cost
A spreadsheet-facing export can reject formula-like cells, prefix them with a documented neutralizing character, or deliver a format with stronger cell typing. Each choice changes the value a downstream reader sees. The policy record should say whether the prefix is part of the stored value, whether a human must remove it, and which applications were tested. Never claim universal protection from one worksheet check.
For machine-facing outputs, keep the raw logical value and a consumer contract instead of applying a display workaround. If the same dataset needs both audiences, create two explicitly named artifacts with separate hashes and descriptions. Link this review to the text encoding and row guide for byte-level concerns, but keep formula semantics as a separate threat boundary.
Policy questions
- Is the file intended for a spreadsheet user, a machine, or both?
- Which leading characters are classified by the owner policy?
- Does neutralization preserve the intended literal value for each target consumer?
- Will a later save and reopen change the cell again?
- Can the output be rejected instead of transformed when policy is unknown?
Use a text-only fixture
A safe fixture tests classification without opening a real workbook or sending a customer value to a spreadsheet application. Keep a field called expected_literal and another called policy_result. Include formula-like starts, an ordinary negative number, an email-shaped identifier, a quoted comma, an embedded line break, a blank, and a leading-zero code. The fixture proves that the checklist distinguishes cases; it does not prove that a particular application will behave identically.
Record output hashes and policy version for each audience. If the owner cannot state whether the prefix is acceptable to the machine consumer, stop at classification. Do not use a live formula, external reference, macro, or customer-export example in the public worksheet.
| Result | Disposition | Next evidence |
|---|---|---|
| Policy matches consumer contract | continue | Run approved consumer fixture |
| Formula-like text is unclassified | hold | Owner chooses reject or neutralize |
| Prefix changes machine value | split artifacts | Publish separate audience contracts |
| Leading zero is lost | hold | Preserve identifier as text |
| Only CSV parser was tested | incomplete | Test spreadsheet interpretation separately |
Synthetic CSV safety ledger
field | expected_literal | target | policy_result
status_note | =review | spreadsheet | classify_then_neutralize
account_code | 0017 | machine | preserve_as_text
contact_alias | @example.test | spreadsheet | classify_then_confirm
comment | "two, words" | both | quote_for_csv_only
empty_note | (empty) | both | distinguish_empty_from_missingWrite the finding in bounded language
Use wording such as “formula-like prefix classified,” “literal text preserved in the synthetic fixture,” or “spreadsheet behavior unverified.” Avoid saying that a CSV is safe in every spreadsheet or that a quoting rule prevents all injection. Also keep this technical finding separate from authorization to export the source values and from a privacy review.
A format guide can identify an output risk; it cannot decide whether a person is authorized to distribute a file. Keep provenance, field classification, and owner approval in separate records. If a CSV is converted to a spreadsheet, record the conversion step because a later save can change cell types or values.
| Finding | Disposition | Do not infer |
|---|---|---|
| Formula-like cell classified and policy tested | bounded pass | All spreadsheet applications are safe |
| Policy chosen but consumer not tested | conditional | The prefix has no downstream cost |
| CSV grammar valid only | grammar pass | Formula semantics are safe |
| Literal values preserved in fixture | fixture pass | Real exports contain no sensitive values |
| Owner permission documented | permission evidence | The content is accurate or valuable |
Close with a qualified preparation step
After the audience, cell policy, synthetic evidence, and downstream trade-offs are documented, keep the export packet at technical review level. Use the data provenance log for transforms and the schema guide for field meaning. Do not upload raw CSV rows merely to test a formula policy.
For a supported non-health collection, with authority to describe the output and a controlled handling boundary, the qualified appraisal path can be a next preparation step. It does not scan CSVs, neutralize formulas, create a quote, match a buyer, issue a legal opinion, or grant a license. The presence of a neutralization policy also does not prove that the source export may be shared.
Takeaways
- Review CSV grammar and spreadsheet semantics as separate layers.
- Classify formula-like starts with synthetic text, never live customer payloads.
- Choose a consumer-specific policy and preserve its downstream cost.
- Keep leading-zero, blank, null, and literal formula-like values distinct.
- Report tested behavior narrowly and leave unverified applications explicit.