logo

CSV injection - Elixir


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

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

Description

Insecure Code Example

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

  1. Sanitize user-provided data before exporting it to a CSV file.
  2. 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.

Secure Code Example

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

  • 090 - CSV injection

  • Last updated

    2023/09/18