HIGH bola idorphoenix

Bola Idor in Phoenix

How Bola Idor Manifests in Phoenix

BOLA/IdOR (Broken Object Level Authorization / Insecure Direct Object References) in Phoenix applications typically occurs when user input directly references objects without proper authorization checks. In Phoenix, this often manifests through dynamic URL parameters that map to database records without verifying the current user's permissions.

Consider a Phoenix controller that fetches a user profile:

def show(conn, %{"id" => id}) do
  user = Accounts.get_user!(id)
  render(conn, "show.html", user: user)
end

This code is vulnerable because it retrieves any user by ID without checking if the requester is authorized to view that user's data. An attacker can simply increment the ID parameter to access other users' profiles.

Another common Phoenix pattern involves nested resources:

def show(conn, %{"user_id" => user_id, "post_id" => post_id}) do
  post = Posts.get_post!(post_id)
  render(conn, "show.html", post: post)
end

Here, the controller fetches a post by ID without verifying it belongs to the user specified in the URL. An authenticated user could access any post in the system by changing the post_id parameter.

Phoenix contexts can also introduce BOLA vulnerabilities when they don't properly scope queries:

def get_user_by_id(id) do
  Repo.get(User, id)
end

If this context function is called without additional authorization logic, it becomes a direct path for object enumeration attacks.

Phoenix-Specific Detection

Detecting BOLA in Phoenix applications requires both manual code review and automated scanning. middleBrick's black-box scanning approach is particularly effective for Phoenix APIs because it tests the actual running application without requiring source code access.

For manual detection, look for these Phoenix-specific patterns:

1. Dynamic Parameter Usage

# Vulnerable: Direct parameter usage
user = Accounts.get_user!(conn.params["id"])

2. Missing Authorization in Context Functions

# Vulnerable: No user scoping
Repo.all(from p in Post)

3. Improper Ecto Query Construction

# Vulnerable: Raw SQL with user input
query = "SELECT * FROM users WHERE id = $1"
Repo.query(query, [conn.params["id"]])

middleBrick scans Phoenix applications by sending authenticated requests with manipulated parameters to test for unauthorized access. For example, it might:

  • Request /api/users/1, then /api/users/2 to check if sequential IDs return different users
  • Test nested routes like /api/users/1/posts/1 vs /api/users/2/posts/1
  • Check if authenticated users can access other users' data through ID manipulation
  • Verify that authorization middleware properly restricts access

The scanner tests 12 security categories in parallel, including BOLA-specific checks that attempt to access objects across user boundaries. middleBrick's LLM/AI security module can also detect if your Phoenix application has unauthenticated AI endpoints that might be vulnerable to prompt injection or excessive agency.

Phoenix-Specific Remediation

Phoenix provides several native features for preventing BOLA vulnerabilities. The most effective approach combines proper context design with authorization checks.

1. Context-Level Authorization

defmodule MyApp.Accounts do
  import Ecto.Query
  
  def get_user_by_id(id, current_user_id) do
    Repo.get_by(User, id: id, user_id: current_user_id)
  end
  
  def list_user_posts(user_id, current_user_id) do
    if user_id == current_user_id do
      Repo.all(from p in Post, where: p.user_id == ^user_id)
    else
      {:error, :unauthorized}
    end
  end
end

2. Controller-Level Authorization

defmodule MyAppWeb.UserController do
  use MyAppWeb, :controller
  alias MyApp.Accounts
  
  def show(conn, %{"id" => id}) do
    with {:ok, user} <- Accounts.get_user_by_id(id, conn.assigns.current_user.id) do
      render(conn, "show.html", user: user)
    else
      {:error, :unauthorized} ->
        conn
        |> put_status(403)
        |> render("forbidden.html")
      {:error, :not_found} ->
        conn
        |> put_status(404)
        |> render("not_found.html")
    end
  end
end

3. Using Phoenix's Plugs for Authorization

defmodule MyAppWeb.Plugs.RequireOwnership do
  import Plug.Conn
  
  def init(opts), do: opts
  
  def call(conn, _opts) do
    user_id = conn.params["user_id"]
    current_user_id = conn.assigns.current_user.id
    
    if user_id != current_user_id do
      conn
      |> send_resp(403, "Forbidden")
      |> halt()
    else
      conn
    end
  end
end

# In router.ex
defmodule MyAppWeb.Router do
  use MyAppWeb, :router
  
  pipeline :owned_resource do
    plug MyAppWeb.Plugs.RequireOwnership
  end
  
  scope "/api", MyAppWeb do
    pipe_through [:api, :auth, :owned_resource]
    
    get "/users/:user_id/posts/:id", PostController, :show
  end
end

4. Using Libraries like Canada or Bodyguard

# With Canada
defmodule MyApp.Policies do
  import Canada
  
  define(User, :index_posts, Post, user_id: id(user.id))
  define(User, :show_post, Post, user_id: id(user.id))
end

# In controller
def show(conn, %{"id" => id}) do
  post = Post |> Repo.get(id) |> authorize(conn, :show_post)
  render(conn, "show.html", post: post)
end

For comprehensive protection, implement the principle of least privilege throughout your Phoenix application. Always scope database queries by the current user's ID, use Phoenix's authorization plugs, and validate ownership before returning any object data.

Related CWEs: bolaAuthorization

CWE IDNameSeverity
CWE-250Execution with Unnecessary Privileges HIGH
CWE-639Insecure Direct Object Reference CRITICAL
CWE-732Incorrect Permission Assignment HIGH

Frequently Asked Questions

How does middleBrick specifically detect BOLA in Phoenix applications?
middleBrick performs black-box scanning by sending authenticated requests with manipulated parameters to test for unauthorized access. It attempts to access objects across user boundaries by incrementing IDs, testing nested routes, and verifying that authorization middleware properly restricts access. The scanner tests 12 security categories in parallel, including BOLA-specific checks that attempt to enumerate objects by changing URL parameters and checking if authenticated users can access other users' data.
Can I integrate middleBrick's BOLA scanning into my Phoenix CI/CD pipeline?
Yes, the middleBrick GitHub Action allows you to add API security checks to your Phoenix CI/CD pipeline. You can configure it to scan your staging APIs before deployment and fail builds if security scores drop below your threshold. The CLI tool also lets you scan from terminal with 'middlebrick scan ' and get JSON output for integration into scripts. Pro plan includes continuous monitoring where APIs are scanned on a configurable schedule with alerts.