External Control of File Name or Path - Elixir

External Control of File Name or Path - Elixir

Need

To prevent unauthorized access and alteration of system files

Context

  • Usage of Elixir for building scalable and fault-tolerant applications
  • Usage of Elixir Phoenix Plug for building web applications
  • Usage of file-upload handling for untrusted sources

Description

Non compliant code

        defmodule VulnerableApp.FileUploadController do
  use VulnerableApp.Web, :controller

  def upload(conn, %{"file" => file, "filename" => filename}) do
    File.write(filename, file)
    send_resp(conn, 200, "File uploaded successfully")
  end
end
        
        

The following Elixir code receives an uploaded file and its filename from an untrusted source and directly uses the given filename to save the file. This leaves the application open to manipulation from an attacker.

Steps

  • Use a library such as `plug` to handle file uploads securely.
  • Do not use the original filename from the user. Generate a new filename on the server side.
  • Restrict the storage of uploaded files to a specific directory.

Compliant code

        defmodule SecureApp.FileUploadController do
  use SecureApp.Web, :controller

  def upload(conn, %{"file" => file}) do
    filename = generate_filename()
    File.write("uploads/" <> filename, file)
    send_resp(conn, 200, "File uploaded successfully")
  end

  defp generate_filename() do
    :crypto.strong_rand_bytes(20) |> Base.url_encode64()
  end
end
        
        

The following Elixir code receives an uploaded file from an untrusted source, generates a new filename and saves the file to a specified directory. This prevents an attacker from manipulating the file name or path.

References