Skip to main content

Privilege Escalation Vulnerability

Need

Prevent unauthorized access to information and operations

Context

  • Usage of Elixir (1.10 and above) for building scalable and fault-tolerant applications
  • Usage of plain maps for role management

Description

Non compliant code

defmodule User do
defstruct [:id, :role, :data]
end

user = %User{id: 1, role: :admin, data: 'secret'}

def execute_action(user, action) do
if user.role == :admin do
IO.puts 'Admin action executed!'
else
IO.puts 'User action executed!'
end
end

This code represents a user system with different roles. An Elixir struct User is defined which holds an id, role, and data. However, due to the lack of a proper access control mechanism, a malicious user can easily manipulate their role in the User struct and escalate their privileges. For example, a user can change their role to 'admin' and gain access to sensitive data or actions they are not supposed to.

Steps

  • Implement proper access control: Ensure the role cannot be easily manipulated by a user.
  • Roles should be controlled with users tokens or the exposure of user ID should be avoided.
  • Encrypt sensitive data and ensure it cannot be accessed without proper authorization.

Compliant code

defmodule User do
defstruct [:id, :token, :data]
end

admins = [1, 2, 3]

user = %User{id: 1, token: :crypto.strong_rand_bytes(16), data: 'secret'}

def execute_action(user, action) do
if user.id in admins do
IO.puts 'Admin action executed!'
else
IO.puts 'User action executed!'
end
end

This revised code introduces a secure token system for role management. It removes the 'role' field from the User struct and instead uses a list of admin user IDs. Also, the user struct now includes a token generated using :crypto.strong_rand_bytes. The token is used for identifying the user instead of the id, thus making it harder to manipulate. The function 'execute_action' checks if the user's id is in the list of admins before allowing an admin action.

References