targets/codex/skills/security/SKILL.md
Enforce Elixir/Phoenix security — auth, OAuth, sessions, CSRF, XSS, SQL injection, input validation, secrets. Use when editing auth files, login flows, RBAC, or API keys.
npx skillsauth add oliver-kriska/claude-elixir-phoenix securityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Ash projects:
AshAuthenticationhas its own strategy/token patterns — use theash-frameworkskill. CSRF, XSS, and secret management patterns below still apply.
Quick reference for security patterns in Elixir/Phoenix.
^ operator, never string interpolationto_existing_atom/1raw/1 with untrusted contentruntime.exs from env varsdef authenticate(email, password) do
user = Repo.get_by(User, email: email)
cond do
user && Argon2.verify_pass(password, user.hashed_password) ->
{:ok, user}
user ->
{:error, :invalid_credentials}
true ->
Argon2.no_user_verify() # Timing attack prevention
{:error, :invalid_credentials}
end
end
# RE-AUTHORIZE IN EVERY EVENT HANDLER
def handle_event("delete", %{"id" => id}, socket) do
post = Blog.get_post!(id)
# Don't trust that mount authorized this action!
with :ok <- Bodyguard.permit(Blog, :delete_post, socket.assigns.current_user, post) do
Blog.delete_post(post)
{:noreply, stream_delete(socket, :posts, post)}
else
_ -> {:noreply, put_flash(socket, :error, "Unauthorized")}
end
end
# ✅ SAFE: Parameterized queries
from(u in User, where: u.name == ^user_input)
# ❌ VULNERABLE: String interpolation
from(u in User, where: fragment("name = '#{user_input}'"))
Path.safe_relative/2 for traversalString.to_existing_atom/1 only<%= %>)raw/1 with untrusted content| Wrong | Right |
|-------|-------|
| "SELECT * FROM users WHERE name = '#{name}'" | from(u in User, where: u.name == ^name) |
| String.to_atom(user_input) | String.to_existing_atom(user_input) |
| <%= raw @user_comment %> | <%= @user_comment %> |
| Hardcoded secrets in config | runtime.exs from env vars |
| Auth only in mount | Re-auth in every handle_event |
For detailed patterns, see:
references/authentication.md - phx.gen.auth, MFA, sessionsreferences/authorization.md - Bodyguard, scopes, LiveView authreferences/input-validation.md - Changesets, file uploads, pathsreferences/security-headers.md - CSP, CSRF, rate limiting, headersreferences/oauth-linking.md - OAuth account linking, token managementreferences/rate-limiting.md - Composite key strategies, Hammer patternsreferences/advanced-patterns.md - SSRF prevention, secrets management, supply chaintools
Compatibility alias for the Elixir/Phoenix plugin's LiveView assigns audit. Invoke explicitly with /lv:assigns.
development
Trace Elixir call trees from entry points via mix xref. Use when debugging data flow, planning signature changes, or understanding how a bug reaches code.
tools
Compatibility alias for the Elixir/Phoenix plugin's N+1 query checker. Invoke explicitly with /ecto:n1-check.
tools
Compatibility alias for the Elixir/Phoenix plugin's Ecto constraint debugger. Invoke explicitly with /ecto:constraint-debug.