Skip to main content

Lack of data validation - Content Spoofing

Need

Prevent unauthorized file replacement

Context

  • Usage of Elixir (1.12 and above) for building scalable and concurrent applications
  • Usage of Plug and Cowboy for HTTP request and response handling

Description

Non compliant code

defmodule FileUploadController do
use MyApp.Web, :controller

def create(conn, %{'file' => file_params}) do
File.write!(Path.join("uploads/", file_params["name"]), file_params["content"])
send_resp(conn, 200, "File uploaded successfully")
end
end

This controller allows a user to upload a file with any name to the 'uploads/' directory. If a file with the same name already exists, it will be overwritten without any checks or validations. This allows an attacker to upload arbitrary files, overwriting any existing files with the same name.

Steps

  • Add an additional check before writing the file to see if a file with the same name already exists.
  • If a file already exists with the same name, return an error response or ask for confirmation before overwriting.

Compliant code

defmodule FileUploadController do
use MyApp.Web, :controller

def create(conn, %{'file' => file_params}) do
if File.exists?(Path.join("uploads/", file_params["name"])) do
send_resp(conn, 400, "A file with the same name already exists.")
else
File.write!(Path.join("uploads/", file_params["name"]), file_params["content"])
send_resp(conn, 200, "File uploaded successfully")
end
end
end

In the secure code example, an additional check has been added to see if a file with the same name already exists before writing the file. If a file already exists with the same name, an error response is returned.

References