How to fix SQL Injection (Legacy & Modern)
in Plug
Executive Summary
SQL injection in the Elixir ecosystem typically occurs when developers bypass Ecto's safety layers to execute raw SQL within a Plug or Phoenix controller. If you are interpolating user-controlled strings directly into your SQL statements, you are handing over your database keys to any script kiddie with a browser. To secure a Plug-based application, you must enforce strict parameterization.
The Vulnerable Pattern
defmodule MyApp.UserPlug do
import Plug.Conn
def init(opts), do: opts
def call(conn, _opts) do
user_id = conn.params["id"]
# VULNERABLE: String interpolation creates a classic SQLi vector
sql = "SELECT * FROM users WHERE id = '" <> user_id <> "';"
{:ok, result} = Ecto.Adapters.SQL.query(MyApp.Repo, sql, [])
send_resp(conn, 200, "Data retrieved")
end
end
The Secure Implementation
The vulnerability exists because the database engine cannot distinguish between the developer's SQL commands and the user's input when they are concatenated into a single string. By switching to parameterized queries (using $1, $2 placeholders), you send the query template and the data in separate packets to the database driver. The driver ensures the input is treated strictly as a literal value, never as executable code. For modern Elixir apps, the Ecto DSL is the preferred defense-in-depth mechanism as it uses the pin operator (^) to safely bind variables.
defmodule MyApp.UserPlug do import Plug.Conn def init(opts), do: opts def call(conn, _opts) do user_id = conn.params["id"] # SECURE: Using parameterized queries ($1) and passing parameters separately sql = "SELECT * FROM users WHERE id = $1;" {:ok, result} = Ecto.Adapters.SQL.query(MyApp.Repo, sql, [user_id])# BETTER: Using Ecto Query DSL which handles parameterization automatically # user = MyApp.Repo.get(MyApp.User, user_id) send_resp(conn, 200, "Data retrieved")
end end
Your Plug API
might be exposed to SQL Injection (Legacy & Modern)
74% of Plug 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.