Skip to content
cccskills
FreePublished on GitHub

security

Build and harden Phoenix auth and security — OAuth login, password hashing, sessions, RBAC, rate limiting, CSRF, XSS, SQL injection, secrets. Use when adding login flows or permissions, or handling user input.

The English summary is being prepared. Showing the original description.

See how to install

Files included (8)

  • SKILL.md4.3 KB
  • references/advanced-patterns.md7.0 KB
  • references/authentication.md2.1 KB
  • references/authorization.md2.1 KB
  • references/input-validation.md3.2 KB
  • references/oauth-linking.md4.5 KB
  • references/rate-limiting.md6.2 KB
  • references/security-headers.md2.5 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Elixir/Phoenix Security Reference

Ash projects: AshAuthentication has its own strategy/token patterns — use the ash-framework skill. CSRF, XSS, and secret management patterns below still apply.

Quick reference for security patterns in Elixir/Phoenix.

Iron Laws — Never Violate These

  1. VALIDATE AT BOUNDARIES — Never trust client input. All data through changesets
  2. NEVER INTERPOLATE USER INPUT — Use Ecto's ^ operator, never string interpolation
  3. NO String.to_atom WITH USER INPUT — Atom exhaustion DoS. Use to_existing_atom/1
  4. AUTHORIZE EVERYWHERE — Check in contexts AND re-validate in LiveView events
  5. ESCAPE BY DEFAULT — Never use raw/1 with untrusted content
  6. SECRETS NEVER IN CODE — All secrets in runtime.exs from env vars
  7. LIVEVIEW EVENT PARAMS ARE UNTRUSTED — Users can alter forms, hooks, and every phx-value-* in DevTools. Validate and authorize against server-side state before acting

Quick Patterns

Timing-Safe Authentication

def 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

LiveView Authorization (CRITICAL)

# `id` is client input even when it came from phx-value-id.
# 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

Rendered LiveView events can expose IDs in HTML and websocket payloads. That is not automatically a vulnerability: treat IDs as public identifiers, never as proof of access. Use opaque references only when the identifier itself must not be disclosed, and still perform server-side authorization.

SQL Injection Prevention

# ✅ SAFE: Parameterized queries
from(u in User, where: u.name == ^user_input)

# ❌ VULNERABLE: String interpolation
from(u in User, where: fragment("name = '#{user_input}'"))

Quick Decisions

What to validate?

  • All user input → Ecto changesets
  • File uploads → Extension + magic bytes + size
  • Paths → Path.safe_relative/2 for traversal
  • Atoms → String.to_existing_atom/1 only

What to escape?

  • HTML output → Auto-escaped by default (<%= %>)
  • User HTML → HtmlSanitizeEx with scrubber
  • Never → raw/1 with untrusted content

Anti-patterns

WrongRight
"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 configruntime.exs from env vars
Auth only in mountRe-auth in every handle_event
Trusting phx-value-* or hidden IDsLoad server-side state and authorize it

References

For detailed patterns, see:

  • ${CLAUDE_SKILL_DIR}/references/authentication.md - phx.gen.auth, MFA, sessions
  • ${CLAUDE_SKILL_DIR}/references/authorization.md - Bodyguard, scopes, LiveView auth
  • ${CLAUDE_SKILL_DIR}/references/input-validation.md - Changesets, file uploads, paths
  • ${CLAUDE_SKILL_DIR}/references/security-headers.md - CSP, CSRF, rate limiting, headers
  • ${CLAUDE_SKILL_DIR}/references/oauth-linking.md - OAuth account linking, token management
  • ${CLAUDE_SKILL_DIR}/references/rate-limiting.md - Composite key strategies, Hammer patterns
  • ${CLAUDE_SKILL_DIR}/references/advanced-patterns.md - SSRF prevention, secrets management, supply chain

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Analyze a legacy app in any language before rewriting it in Elixir: inventory, features as goals, why each mechanism exists, runtime topology, external contracts. Use to start or refresh a rewrite.

The English summary is being prepared. Showing the original description.

oliver-kriska/claude-elixir-phoenix567Updated Oct 17, 2026

Design the idiomatic Elixir architecture for a rewrite: set the compatibility bar (ADR-000), consult phx specialists on open questions, then build contexts, ledger and ADRs. Use after /rewrite:analyze.

The English summary is being prepared. Showing the original description.

oliver-kriska/claude-elixir-phoenix567Updated Oct 17, 2026

Ash Framework — resources, actions, policies, aggregates; Use when generating resources via mix ash.codegen, editing…

The English summary is being prepared. Showing the original description.

oliver-kriska/claude-elixir-phoenix567Updated Oct 17, 2026

Ash Framework — resources, actions, policies, aggregates, calculations, AshPhoenix.Form, LiveView, migrations. Use when generating resources via mix ash.codegen, editing changes, checks, types, validations, or domain code interfaces.

The English summary is being prepared. Showing the original description.

oliver-kriska/claude-elixir-phoenix567Updated Oct 17, 2026

Compatibility alias for the Elixir/Phoenix plugin's LiveView assigns audit. Invoke explicitly with /lv:assigns.

The English summary is being prepared. Showing the original description.

oliver-kriska/claude-elixir-phoenix567Updated Oct 17, 2026

Inspect LiveView socket assigns for memory bloat — missing temporary_assigns, unused assigns, unbounded lists needing streams, memory estimates. Use when LiveView memory grows or you need to add temporary_assigns.

The English summary is being prepared. Showing the original description.

oliver-kriska/claude-elixir-phoenix567Updated Oct 17, 2026

See all skills by oliver-kriska

Report a problem with this skill