Insecure Object Reference in Credit Card Inquiry
Need
Prevent unauthorized access to sensitive user information
Context
- Usage of Elixir 1.12 for functional programming on the Erlang virtual machine
- Usage of Phoenix Framework 1.6 for web development
Description
Non compliant code
defmodule MyApp.CreditCardController do
use MyApp, :controller
def show(conn, %{'id' => id}) do
credit_card = CreditCard.get!(id)
render(conn, 'show.json', credit_card: credit_card)
end
end
The code is vulnerable because it allows the querying of credit card information based on the encrypted product number, but it does not verify if the account making the request has the necessary permissions to access that specific credit card information. This opens a pathway for an attacker to probe and potentially obtain sensitive credit card information.
Steps
- Import the Plug.Conn library which provides utility functions for working with connections
- Use the Plug.Conn.assign/3 function in your controller to assign the current user to the conn struct
- Check if the current user has the necessary permissions to access the requested credit card data before returning it
- Add an else clause to handle scenarios when the user does not have permission to access the data
Compliant code
defmodule MyApp.CreditCardController do
use MyApp, :controller
import Plug.Conn
def show(conn, %{'id' => id}) do
credit_card = CreditCard.get!(id)
if conn.assigns.current_user.id == credit_card.user_id do
render(conn, 'show.json', credit_card: credit_card)
else
conn
|> put_status(:forbidden)
|> put_resp_header('content-type', 'application/json')
|> send_resp(403, '{"error": "Not authorized"}')
end
end
end
This code is secure because it verifies if the user making the request has the necessary permissions to access the requested credit card data before providing it. This is achieved by comparing the user id in the session with the user id associated with the credit card. If the ids match, the information is provided. Otherwise, an error message is returned.