T09 · Insecure Skill Coding Practices
- Location
outreach-crm.js:321- Finding
CSV Formula Injection in Lead Export
- Content
View full analysis
Vulnerability Details
File Location:
outreach-crm.js, lines 321–329
Vulnerability Type: CSV formula injection
Risk Level: MediumVulnerable Code
js const escape = (v) => `"${String(v ?? '').replace(/"/g, '""')}"`; const header = allKeys.join(','); const rows = leads.map(lead => allKeys.map(k => escape(Array.isArray(lead[k]) ? lead[k].join('; ') : lead[k])).join(',') ); const csv = [header, ...rows].join('\n'); fs.mkdirSync(WORKSPACE_DIR, { recursive: true }); fs.writeFileSync(CSV_FILE, csv, 'utf8');Technical Analysis
Lead fields are attacker- or user-controlled and are persisted by
saveLeadToFile(). During CSV export, the implementation only doubles quotation marks and surrounds each value with quotes. This provides CSV syntax escaping but does not neutralize spreadsheet formulas.Spreadsheet applications may evaluate cells whose first non-whitespace character is
=,+,-, or@, even when the value is quoted in the CSV file. A field such as a lead name, handle, source, or interaction-derived property can therefore contain a formula that remains active in the generatedleads.csv.Attack Path
- An attacker supplies a crafted lead field beginning with a spreadsheet formula marker, such as
=,+,-, or@. - The
add-leadcommand parses the value andsaveLeadToFile()stores it inleads.jsonwithout formula neutralization. - The user invokes
export-csv. exportLeadsAsCSV()writes the malicious value toleads.csv, escaping only CSV quotation marks.- The user downloads and opens the CSV file in spreadsheet software.
- If the spreadsheet application permits formula evaluation, the crafted cell is interpreted as a formula rather than inert text.
Impact Assessment
Exploitation occurs in the context of the user opening the exported file and is constrained by the behavior and security settings of the spreadsheet application. A success ...[truncated 441 chars]
- An attacker supplies a crafted lead field beginning with a spreadsheet formula marker, such as
- Remediation
View remediation
Remediation Suggestions
Neutralize formula-capable values before performing ordinary CSV escaping:
- Convert each value to a string.
- Detect whether its first non-whitespace character is
=,+,-, or@. - Prefix matching values with an apostrophe so spreadsheet applications treat them as text.
- Continue doubling embedded quotation marks and quoting every cell.
- Consider rejecting or removing unsafe control characters.
- Add tests covering every formula prefix, leading whitespace, embedded quotes, arrays, and ordinary values.
- Document that lead fields are untrusted and that CSV exports should be opened with formula execution disabled where possible.
Example hardening:
js const escapeCSV = (value) => { let text = String(value ?? ''); if (/^[\t\r\n ]*[=+\-@]/.test(text)) { text = `'${text}`; } return `"${text.replace(/"/g, '""')}"`; };
