How to fix NoSQL Injection
in Phoenix
Executive Summary
NoSQL injection in Phoenix/Elixir environments typically manifests when using Ecto adapters for document-based stores like MongoDB. The vulnerability triggers when raw, unsanitized user-controlled maps (params) are passed directly into query functions. Attackers exploit this by injecting operator keys such as '$gt', '$ne', or '$regex' to bypass authentication logic or dump the entire database state.
The Vulnerable Pattern
def list_users(conn, %{"filter" => filter}) do
# CRITICAL: Directly passing a user-controlled map into the where clause
# An attacker can send: filter[$ne]=null to dump all users
users = User
|> Ecto.Query.where(^filter)
|> Repo.all()
render(conn, "index.json", users: users)
end
The Secure Implementation
The exploit leverages the query adapter's tendency to interpret nested maps as NoSQL operators. To kill this bug: 1. Never pass raw params maps into Ecto's `where` or `filter`. 2. Use pattern matching in your controller/context to extract only the expected primitive types (strings, ints). 3. Always use the pin operator (`^`) to bind values to query placeholders, which ensures the NoSQL adapter treats the input as data, not as a query directive. 4. Implement strict Ecto.Changeset validation to drop any keys that don't match your schema's expected types.
def list_users(conn, %{"username" => username}) when is_binary(username) do # MITIGATION: Explicitly bind specific keys and use the pin operator (^) # This forces the adapter to treat the input as a literal value, not a command users = User |> Ecto.Query.where([u], u.username == ^username) |> Repo.all() render(conn, "index.json", users: users) end
def list_users(conn, _params), do: send_resp(conn, 400, “Invalid Input”)
Your Phoenix API
might be exposed to NoSQL Injection
74% of Phoenix apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.