mcpField
S
security

security

github.com/oliver-kriska安全57151 次安装1 周前更新
代码仓库

关于 security

面向 Elixir 和 Phoenix 开发者的安全参考,汇总输入验证、授权、转义、密钥管理与注入风险防护要点,也涵盖 LiveView 事件检查。

主要功能

  1. 01使用 changeset 在边界验证
  2. 02参数化 Ecto 查询模式
  3. 03LiveView 事件授权
  4. 04安全转义与 Atom 处理
  5. 05运行时密钥管理

适用场景

  1. 01检查用户输入处理方式
  2. 02保护 LiveView 事件处理器
  3. 03防范 SQL 注入与 Atom 耗尽
  4. 04检查密钥存储和 HTML 转义

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/oliver-kriska/claude-elixir-phoenix --skill security

安装后在 Claude Code 中输入/security确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
advanced-patterns.md
authentication.md
authorization.md
input-validation.md
oauth-linking.md
rate-limiting.md
security-headers.md

详细介绍

Elixir/Phoenix 安全参考

Ash 项目:AshAuthentication 有自己的策略/令牌模式——请使用 ash-framework 技能。以下 CSRF、XSS 和密钥管理模式仍然适用。

Elixir/Phoenix 安全模式速查。

铁律——绝不可违反

  1. 在边界处验证——绝不信任客户端输入。所有数据都必须通过 changeset
  2. 绝不插入用户输入——使用 Ecto 的 ^ 运算符,绝不进行字符串插值
  3. 绝不对用户输入使用 String.to_atom——这会导致 Atom 耗尽型 DoS。请使用 to_existing_atom/1
  4. 在所有位置进行授权——在上下文中检查,并在 LiveView 事件中重新验证
  5. 默认转义——绝不对不可信内容使用 raw/1
  6. 代码中绝不包含密钥——所有密钥都应从环境变量加载到 runtime.exs
  7. LiveView 事件参数不可信——用户可以在 DevTools 中修改表单、钩子以及所有 phx-value-*。操作前,请根据服务器端状态进行验证和授权

常用模式

时序安全的身份验证
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 授权(重要)
# `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

渲染后的 LiveView 事件可能会在 HTML 和 WebSocket 载荷中暴露 ID。这不一定是漏洞:应将 ID 视为公开标识符,绝不可将其视为访问权限的证明。只有在标识符本身必须保密时才使用不透明引用,并且仍须在服务器端执行授权。

SQL 注入防护
# ✅ SAFE: Parameterized queries
from(u in User, where: u.name == ^user_input)

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

快速决策

应验证哪些内容?
  • 所有用户输入 → Ecto changeset
  • 文件上传 → 扩展名 + 魔数 + 大小
  • 路径 → 使用 Path.safe_relative/2 防止路径遍历
  • Atom → 仅使用 String.to_existing_atom/1
应转义哪些内容?
  • HTML 输出 → 默认自动转义(<%= %>)
  • 用户 HTML → 使用带 scrubber 的 HtmlSanitizeEx
  • 绝不 → 对不可信内容使用 raw/1

反模式

错误正确
"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 %>
在配置中硬编码密钥从环境变量加载到 runtime.exs
只在 mount 中进行身份验证在每个 handle_event 中重新进行身份验证
信任 phx-value-* 或隐藏 ID从服务器端加载状态并进行授权

参考资料

详细模式请参阅:

  • ${CLAUDE_SKILL_DIR}/references/authentication.md - phx.gen.auth、MFA、会话
  • ${CLAUDE_SKILL_DIR}/references/authorization.md - Bodyguard、作用域、LiveView 身份验证
  • ${CLAUDE_SKILL_DIR}/references/input-validation.md - Changeset、文件上传、路径
  • ${CLAUDE_SKILL_DIR}/references/security-headers.md - CSP、CSRF、速率限制、标头
  • ${CLAUDE_SKILL_DIR}/references/oauth-linking.md - OAuth 账号关联、令牌管理
  • ${CLAUDE_SKILL_DIR}/references/rate-limiting.md - 复合键策略、Hammer 模式
  • ${CLAUDE_SKILL_DIR}/references/advanced-patterns.md - SSRF 防护、密钥管理、供应链

评论

支持 Markdown