Automatic information enumeration - Personal Information
Need
To prevent unauthorized access to user's personal information.
Context
- Usage of Elixir (1.12.0 and above) for building scalable and fault-tolerant applications
- Usage of Phoenix Framework for web development
- Usage of Ecto for database interactions
Description
Non compliant code
defmodule MyApp.UserController do
use MyApp, :controller
def show(conn, %{'id' => id}) do
user = MyApp.Repo.get(MyApp.User, id)
render(conn, 'show.html', user: user)
end
end
This code is vulnerable because it fetches and returns user information based solely on the user ID provided in the request, without any authentication or authorization checks. An attacker could potentially iterate over user IDs to retrieve personal information about all users.
Steps
- Authenticate the user before accessing the 'show' action.
- Authorize the user to only access their own user information.
Compliant code
defmodule MyApp.UserController do
use MyApp, :controller
def show(conn, %{'id' => id}) do
current_user = get_authenticated_user(conn)
if current_user && current_user.id == id do
render(conn, 'show.html', user: current_user)
else
send_resp(conn, :unauthorized, '')
end
end
defp get_authenticated_user(conn) do
# Fetch the current user from the session
end
end
This secure code example introduces authentication and authorization checks. Before accessing a user's information, the current user is fetched from the session, and the user can only access their own information. If an unauthenticated user or a user trying to access someone else's information attempts to use the 'show' action, they receive an 'unauthorized' response.