Skip to main content

Insecure object reference - Corporate information

Need

Prevent unauthorized modification of third-party company's employee information

Context

  • Usage of Elixir (v1.12+) for building scalable and fault-tolerant applications
  • Usage of Phoenix Framework for building web applications
  • Usage of Ecto for data persistence
  • Usage of CSV or Excel file uploading and parsing

Description

Non compliant code

defmodule PayrollController do
def upload(conn, %{'file' => file, 'payrollNumber' => payroll_number}) do
{:ok, company} = Repo.get(Company, payroll_number)
Employee.import_from_excel(file, company)
end
end

The code below is insecure because it allows anyone to upload an Excel file and update employee information of any company by changing the 'payrollNumber'. An attacker can change the 'payrollNumber' to a company they do not own and upload or modify its employees' information.

Steps

  • Store the authenticated user's company identifier in the session after successful login.
  • Instead of getting the company identifier from request parameters, get it from the session.
  • Use the company identifier from the session to get the company and update its employees.

Compliant code

defmodule PayrollController do
def upload(conn, %{'file' => file}) do
payroll_number = get_session(conn, :payroll_number)
{:ok, company} = Repo.get(Company, payroll_number)
Employee.import_from_excel(file, company)
end
end

The code below is secure because it uses the 'payrollNumber' stored in the session to get the company and update its employees. Even if an attacker changes the 'payrollNumber' in the request parameters, it won't affect which company's employees are updated because the 'payrollNumber' in the session is used.

References