CSV injection
Need
Prevention of CSV injection attacks
Context
- Usage of TypeScript for type-checking and compiling JavaScript code
- Usage of Express for building web applications and handling HTTP requests
- Usage of csv-writer for writing data to CSV files
Description
Non compliant code
import express from 'express';
import csv from 'csv-writer';
const app = express();
app.get('/export', (req, res) => {
const data = [
{ name: 'John Doe', email: '=SUM(1+2)' },
{ name: 'Jane Smith', email: '[email protected]' },
];
const csvWriter = csv.createObjectCsvWriter({
path: 'export.csv',
header: [
{ id: 'name', title: 'Name' },
{ id: 'email', title: 'Email' },
],
});
csvWriter.writeRecords(data)
.then(() => {
res.download('export.csv');
})
.catch((err) => {
res.status(500).send('Error exporting CSV');
});
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The vulnerability in this code is a CSV injection.
In the data
array, there is a field called email
that contains the value '=SUM(1+2)'
. When this data is written to the CSV file using the csvWriter.writeRecords(data)
function, the value '=SUM(1+2)'
is written as is, without any sanitization or validation.
CSV files can be opened in spreadsheet applications like Excel, and when a cell in a CSV file starts with an equal sign (=
), Excel interprets it as a formula. In this case, the injected formula =SUM(1+2)
would be executed by Excel, resulting in the value 3
being displayed in the corresponding cell.
This vulnerability allows an attacker to inject malicious formulas into the exported CSV file. Depending on the capabilities of the formula language, an attacker could potentially execute arbitrary code, access sensitive data, or perform other malicious actions.
To mitigate this vulnerability, all fields that will be exported to the CSV file should be properly sanitized or escaped to prevent any unintended interpretation as formulas by spreadsheet applications.
Steps
- Sanitize the 'email' field before writing it to the CSV file. Remove any special characters or formulas that could be interpreted by Excel.
- Use a library or function to sanitize the 'email' field, such as the 'sanitize-html' library or a custom sanitization function.
- Update the code to use the sanitized value for the 'email' field when writing records to the CSV file.
- Test the updated code to ensure that the 'email' field is properly sanitized and does not contain any malicious formulas.
Compliant code
import express from 'express';
import csv from 'csv-writer';
import sanitizeHtml from 'sanitize-html';
const app = express();
app.get('/export', (req, res) => {
const data = [
{ name: 'John Doe', email: '=SUM(1+2)' },
{ name: 'Jane Smith', email: '[email protected]' },
];
const sanitizedData = data.map((record) => {
return {
name: record.name,
email: sanitizeHtml(record.email),
};
});
const csvWriter = csv.createObjectCsvWriter({
path: 'export.csv',
header: [
{ id: 'name', title: 'Name' },
{ id: 'email', title: 'Email' },
],
});
csvWriter.writeRecords(sanitizedData)
.then(() => {
res.download('export.csv');
})
.catch((err) => {
res.status(500).send('Error exporting CSV');
});
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The fixed code addresses the vulnerability by sanitizing the data before exporting it to a CSV file. Here's how it works:
-
The code imports the necessary modules:
express
for creating the server,csv-writer
for generating the CSV file, andsanitize-html
for sanitizing the data. -
The code defines an Express route handler for the
/export
endpoint. -
Inside the route handler, an array of data objects is created. Each object represents a record with a
name
and anemail
field. Theemail
field contains a potentially malicious formula (=SUM(1+2)
). -
The
sanitizedData
array is created by mapping over the original data array. For each record, thesanitizeHtml
function is used to sanitize theemail
field, removing any potentially harmful HTML or formulas. -
The
csvWriter
object is created usingcreateObjectCsvWriter
from thecsv-writer
module. It specifies the file path and the headers for the CSV file. -
The
writeRecords
method ofcsvWriter
is called with the sanitized data array. This writes the records to the CSV file. -
If the writing process is successful, the server responds with the CSV file for download using the
res.download
method. -
If any error occurs during the writing process, the server responds with a 500 status code and an error message.
-
Finally, the server starts listening on port 3000.
By using the sanitizeHtml
function to sanitize the email
field before exporting it to the CSV file, the code prevents any potentially malicious formulas from being injected and executed when the CSV file is opened in Excel.