logo

Database

External Control of File Name or Path

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

1. 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.

2. 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.

3. Secure code example

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")
...

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.