Summary
CSV export writes uploaded/user-controlled values directly to CSV. Spreadsheet apps can interpret values starting with formula characters as formulas when the exported file is opened.
Evidence
src/lib/utils/csvParser.ts:31-38 calls Papa.unparse directly on provided headers/rows.
src/app/(main)/admin/tasks/[taskId]/page.tsx:62-92 builds export rows from uploaded CSV values, worker submissions, reviewer comments, and column names.
Impact
If a cell or header starts with =, +, -, @, tab, or carriage return, Excel/Google Sheets may execute it as a formula. This can enable spreadsheet formula injection, misleading exported data, or data exfiltration when an admin/researcher opens the CSV.
Minimal Fix
- Escape spreadsheet-dangerous strings before
Papa.unparse.
- Apply escaping to both headers and cell values because headers originate from uploaded CSV column names.
- Common minimal mitigation: prefix dangerous values with a single quote.
Example condition:
/^[=+\-@\t\r]/.test(value)
Acceptance Criteria
- Exported values beginning with
=, +, -, @, tab, or carriage return are neutralized in the downloaded CSV.
- Normal text values remain unchanged.
- A small unit test or manual fixture confirms dangerous cells are escaped before export.
Summary
CSV export writes uploaded/user-controlled values directly to CSV. Spreadsheet apps can interpret values starting with formula characters as formulas when the exported file is opened.
Evidence
src/lib/utils/csvParser.ts:31-38callsPapa.unparsedirectly on provided headers/rows.src/app/(main)/admin/tasks/[taskId]/page.tsx:62-92builds export rows from uploaded CSV values, worker submissions, reviewer comments, and column names.Impact
If a cell or header starts with
=,+,-,@, tab, or carriage return, Excel/Google Sheets may execute it as a formula. This can enable spreadsheet formula injection, misleading exported data, or data exfiltration when an admin/researcher opens the CSV.Minimal Fix
Papa.unparse.Example condition:
Acceptance Criteria
=,+,-,@, tab, or carriage return are neutralized in the downloaded CSV.