ListMatchGenie

CSV injection protection

Every CSV and XLSX export escapes formula-prefix characters to prevent malicious formulas from executing when recipients open the file in Excel or Google Sheets.

If an exported CSV contains a cell starting with =, +, -, or @, Excel and Google Sheets will interpret that cell as a formula when the file is opened. A malicious cell value like =cmd|' /c calc'!A1 has historically been used to execute arbitrary commands on the recipient's machine.

CSV injection is the attack that exploits this. It doesn't require a software bug — the spreadsheet apps are behaving as designed. The fix has to happen at the data source.

ListMatchGenie prevents this attack by sanitizing every exported cell.

The sanitization rule

Every cell value whose first character is one of:

  • = — formula start
  • + — formula start
  • - — formula start or negative number (handled specially)
  • @ — lookup function
  • | — pipe (in some locale configs)
  • Tab or carriage-return characters

...is prefixed with a single-quote character (') before export. The apostrophe tells Excel/Sheets to treat the cell as literal text, not a formula. The apostrophe is invisible when the cell is viewed normally.

What this looks like in practice

Your source data has a cell like:

=HYPERLINK("https://example.com","Click me")

The exported CSV contains:

'=HYPERLINK("https://example.com","Click me")

When opened in Excel, the cell displays =HYPERLINK("https://example.com","Click me") as text — not as a clickable link, not as anything executable.

When negative numbers need special handling

A cell containing -47.50 is a legitimate negative number, not a formula. The Genie distinguishes these:

  • Pure numeric (matches ^-?\d+(\.\d+)?$) — not escaped, exports as -47.50
  • Looks like formula (contains letters, equals signs, or function names after the leading character) — escaped

Edge case: --47 (double negative) is escaped. This is technically still a formula start in Excel.

Escaping in XLSX

XLSX doesn't have the same injection vulnerability at the format level — cells are typed, so a cell typed as "string" won't be interpreted as formula. But if ListMatchGenie were to write a string-typed cell with a leading =, Excel might offer to convert it to a formula on save-and-reopen. To avoid even that ambiguity, the same escape is applied to string cells in XLSX exports.

Escaping in PDF/PPTX

PDF and PPTX exports aren't at risk — they're not machine-readable data formats. No escaping is applied.

What the recipient sees

A recipient opens your export in Excel/Sheets and sees the cells exactly as they were in your source data, minus any latent formula execution. If you want to preserve literal =SUM(...) text in a cell, that works — it's just displayed as text.

If the recipient wants to remove the escape and actually use the formula, they can edit the cell and delete the leading apostrophe. That's a deliberate action, not an automatic exploit.

Exceptions

In one narrow case, the escape is bypassed: ListMatchGenie's own _lmg_ columns never contain user-controlled data and are exported without sanitization (they don't need it). Every other column is sanitized.

Why this isn't a default in other tools

Many CSV exporters don't do this, either because:

  • The developers weren't aware of CSV injection (it's not as well-known as XSS or SQL injection)
  • They considered it the recipient's responsibility to handle
  • They didn't want the apostrophe visible when the file is opened in non-Excel tools

We chose to always escape because we care more about our customers' customers not getting exploited than about the apostrophe being perfectly invisible in every tool. The apostrophe is invisible in Excel and Sheets (the tools 95% of recipients use). In raw-text editors it appears but doesn't affect functionality.