Skip to main content

CSV injection

Need

To protect against malicious injection of formulas into fields that are exported as part of CSV files and potentially interpreted by Excel or other spreadsheet software.

Context

  • Usage of Elixir for building scalable and fault-tolerant applications
  • Usage of Elixir CSV library for handling CSV files
  • Exporting user-provided data to CSV files

Description

Non compliant code

defmodule VulnerableApp do
def create_csv(data, filename) do
{:ok, file} = File.open(filename, [:write])
Enum.each(data, fn row ->
IO.write(file, Enum.join(row, ",") <> "\n")
end)
File.close(file)
end
end

The following Elixir code writes user-provided data directly to a CSV file without sanitization. This allows a user to inject a formula, which could be executed when the CSV file is opened in a spreadsheet software.

Steps

  • Sanitize user-provided data before exporting it to a CSV file.
  • If the data includes numbers or strings that start with '=', '+', '-', '@', consider prepending the string with a single quote (') to prevent spreadsheet software from interpreting it as a formula.

Compliant code

defmodule SecureApp do
def create_csv(data, filename) do
{:ok, file} = File.open(filename, [:write])
Enum.each(data, fn row ->
sanitized_row = Enum.map(row, &sanitize_field/1)
IO.write(file, Enum.join(sanitized_row, ",") <> "\n")
end)
File.close(file)
end

defp sanitize_field(field) when is_binary(field) do
if String.starts_with?(field, ["=", "+", "-", "@"]) do
"'" <> field
else
field
end
end
defp sanitize_field(field), do: field
end

The following Elixir code sanitizes user-provided data by prepending any field starting with '=', '+', '-', '@' with a single quote, before writing it to a CSV file. This prevents any injected formulas from being interpreted by spreadsheet software.

References