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.