CSV injection - Elixir

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

  • 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