Agent Skills by ALSEL
Anthropic Claudeセキュリティ⭐ リポ 0品質スコア 50/100

convex-security-check

認証、関数の公開範囲、引数のバリデーション、行レベルのアクセス制御、環境変数の取り扱いを網羅した、Convexアプリ向けのセキュリティ監査チェックリストを素早く実行します。

description の原文を見る

Quick security audit checklist covering authentication, function exposure, argument validation, row-level access control, and environment variable handling

SKILL.md 本文

Convex Security Check

Convex アプリケーションのセキュリティを監査するためのクイックチェックリストです。認証、関数公開、引数検証、行レベルアクセス制御、環境変数処理を網羅しています。

ドキュメントソース

実装前に、推測ではなく最新ドキュメントを確認してください:

使用方法

セキュリティチェックリスト

このチェックリストを使用して、Convex アプリケーションのセキュリティを素早く監査してください:

1. 認証

  • 認証プロバイダが設定されている (Clerk、Auth0 など)
  • すべての機密クエリが ctx.auth.getUserIdentity() を確認している
  • 認証なしのアクセスが意図的に許可されている場所が明記されている
  • セッショントークンが適切に検証されている

2. 関数公開

  • パブリック関数 (querymutationaction) をレビューした
  • 内部関数は internalQueryinternalMutationinternalAction を使用している
  • 機密操作がパブリック関数として公開されていない
  • HTTP アクションがオリジン/認証を検証している

3. 引数検証

  • すべての関数に明示的な args バリデータがある
  • すべての関数に明示的な returns バリデータがある
  • 機密データに v.any() が使用されていない
  • ID バリデータが正しいテーブル名を使用している

4. 行レベルアクセス制御

  • ユーザーは自身のデータのみアクセスできる
  • 管理者関数がユーザーロールを確認している
  • 共有リソースに適切なアクセスチェックがある
  • 削除関数が所有権を検証している

5. 環境変数

  • API キーが環境変数に保存されている
  • コードやスキーマにシークレットがない
  • 開発環境/本番環境で異なるキーを使用している
  • 環境変数は action でのみアクセスされている

認証チェック

// convex/auth.ts
import { query, mutation } from "./_generated/server";
import { v } from "convex/values";
import { ConvexError } from "convex/values";

// Helper to require authentication
async function requireAuth(ctx: QueryCtx | MutationCtx) {
  const identity = await ctx.auth.getUserIdentity();
  if (!identity) {
    throw new ConvexError("Authentication required");
  }
  return identity;
}

// Secure query pattern
export const getMyProfile = query({
  args: {},
  returns: v.union(v.object({
    _id: v.id("users"),
    name: v.string(),
    email: v.string(),
  }), v.null()),
  handler: async (ctx) => {
    const identity = await requireAuth(ctx);
    
    return await ctx.db
      .query("users")
      .withIndex("by_tokenIdentifier", (q) => 
        q.eq("tokenIdentifier", identity.tokenIdentifier)
      )
      .unique();
  },
});

関数公開チェック

// PUBLIC - Exposed to clients (review carefully!)
export const listPublicPosts = query({
  args: {},
  returns: v.array(v.object({ /* ... */ })),
  handler: async (ctx) => {
    // Anyone can call this - intentionally public
    return await ctx.db
      .query("posts")
      .withIndex("by_public", (q) => q.eq("isPublic", true))
      .collect();
  },
});

// INTERNAL - Only callable from other Convex functions
export const _updateUserCredits = internalMutation({
  args: { userId: v.id("users"), amount: v.number() },
  returns: v.null(),
  handler: async (ctx, args) => {
    // This cannot be called directly from clients
    await ctx.db.patch(args.userId, {
      credits: args.amount,
    });
    return null;
  },
});

引数検証チェック

// GOOD: Strict validation
export const createPost = mutation({
  args: {
    title: v.string(),
    content: v.string(),
    category: v.union(
      v.literal("tech"),
      v.literal("news"),
      v.literal("other")
    ),
  },
  returns: v.id("posts"),
  handler: async (ctx, args) => {
    const identity = await requireAuth(ctx);
    return await ctx.db.insert("posts", {
      ...args,
      authorId: identity.tokenIdentifier,
    });
  },
});

// BAD: Weak validation
export const createPostUnsafe = mutation({
  args: {
    data: v.any(), // DANGEROUS: Allows any data
  },
  returns: v.id("posts"),
  handler: async (ctx, args) => {
    return await ctx.db.insert("posts", args.data);
  },
});

行レベルアクセス制御チェック

// Verify ownership before update
export const updateTask = mutation({
  args: {
    taskId: v.id("tasks"),
    title: v.string(),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    const identity = await requireAuth(ctx);
    
    const task = await ctx.db.get(args.taskId);
    
    // Check ownership
    if (!task || task.userId !== identity.tokenIdentifier) {
      throw new ConvexError("Not authorized to update this task");
    }
    
    await ctx.db.patch(args.taskId, { title: args.title });
    return null;
  },
});

// Verify ownership before delete
export const deleteTask = mutation({
  args: { taskId: v.id("tasks") },
  returns: v.null(),
  handler: async (ctx, args) => {
    const identity = await requireAuth(ctx);
    
    const task = await ctx.db.get(args.taskId);
    
    if (!task || task.userId !== identity.tokenIdentifier) {
      throw new ConvexError("Not authorized to delete this task");
    }
    
    await ctx.db.delete(args.taskId);
    return null;
  },
});

環境変数チェック

// convex/actions.ts
"use node";

import { action } from "./_generated/server";
import { v } from "convex/values";

export const sendEmail = action({
  args: {
    to: v.string(),
    subject: v.string(),
    body: v.string(),
  },
  returns: v.object({ success: v.boolean() }),
  handler: async (ctx, args) => {
    // Access API key from environment
    const apiKey = process.env.RESEND_API_KEY;
    
    if (!apiKey) {
      throw new Error("RESEND_API_KEY not configured");
    }
    
    const response = await fetch("https://api.resend.com/emails", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${apiKey}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        from: "noreply@example.com",
        to: args.to,
        subject: args.subject,
        html: args.body,
      }),
    });
    
    return { success: response.ok };
  },
});

完全なセキュリティパターン

// convex/secure.ts
import { query, mutation, internalMutation } from "./_generated/server";
import { v } from "convex/values";
import { ConvexError } from "convex/values";

// Authentication helper
async function getAuthenticatedUser(ctx: QueryCtx | MutationCtx) {
  const identity = await ctx.auth.getUserIdentity();
  if (!identity) {
    throw new ConvexError({
      code: "UNAUTHENTICATED",
      message: "You must be logged in",
    });
  }
  
  const user = await ctx.db
    .query("users")
    .withIndex("by_tokenIdentifier", (q) => 
      q.eq("tokenIdentifier", identity.tokenIdentifier)
    )
    .unique();
    
  if (!user) {
    throw new ConvexError({
      code: "USER_NOT_FOUND",
      message: "User profile not found",
    });
  }
  
  return user;
}

// Check admin role
async function requireAdmin(ctx: QueryCtx | MutationCtx) {
  const user = await getAuthenticatedUser(ctx);
  
  if (user.role !== "admin") {
    throw new ConvexError({
      code: "FORBIDDEN",
      message: "Admin access required",
    });
  }
  
  return user;
}

// Public: List own tasks
export const listMyTasks = query({
  args: {},
  returns: v.array(v.object({
    _id: v.id("tasks"),
    title: v.string(),
    completed: v.boolean(),
  })),
  handler: async (ctx) => {
    const user = await getAuthenticatedUser(ctx);
    
    return await ctx.db
      .query("tasks")
      .withIndex("by_user", (q) => q.eq("userId", user._id))
      .collect();
  },
});

// Admin only: List all users
export const listAllUsers = query({
  args: {},
  returns: v.array(v.object({
    _id: v.id("users"),
    name: v.string(),
    role: v.string(),
  })),
  handler: async (ctx) => {
    await requireAdmin(ctx);
    
    return await ctx.db.query("users").collect();
  },
});

// Internal: Update user role (never exposed)
export const _setUserRole = internalMutation({
  args: {
    userId: v.id("users"),
    role: v.union(v.literal("user"), v.literal("admin")),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    await ctx.db.patch(args.userId, { role: args.role });
    return null;
  },
});

ベストプラクティス

  • 明示的に指示されない限り、npx convex deploy を実行しないこと
  • 明示的に指示されない限り、git コマンドを実行しないこと
  • 機密データを返す前に常にユーザーアイデンティティを検証すること
  • 機密操作には内部関数を使用すること
  • すべての引数を厳密なバリデータで検証すること
  • 更新/削除操作の前に所有権を確認すること
  • API キーを環境変数に保存すること
  • すべてのパブリック関数をセキュリティの観点からレビューすること

よくある落とし穴

  1. 認証チェックの欠落 - 常にアイデンティティを検証する
  2. 内部操作の公開 - internalMutation/Query を使用する
  3. クライアント提供の ID を信頼する - 所有権を検証する
  4. 引数に v.any() を使用する - 具体的なバリデータを使用する
  5. シークレットをハードコードする - 環境変数を使用する

リファレンス

ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
waynesutton
リポジトリ
waynesutton/convexskills
ライセンス
Apache-2.0
最終更新
不明

Source: https://github.com/waynesutton/convexskills / ライセンス: Apache-2.0

関連スキル

Anthropic Claudeセキュリティ⭐ リポ 8,981

secure-code-guardian

認証・認可の実装、ユーザー入力の保護、OWASP Top 10の脆弱性対策が必要な場合に使用します。bcrypt/argon2によるパスワードハッシング、パラメータ化ステートメントによるSQLインジェクション対策、CORS/CSPヘッダーの設定、Zodによる入力検証、JWTトークンの構築などのカスタムセキュリティ実装に対応します。認証、認可、入力検証、暗号化、OWASP Top 10対策、セッション管理、セキュリティ強化全般で活用できます。ただし、構築済みのOAuth/SSO統合や単独のセキュリティ監査が必要な場合は、より特化したスキルの検討をお勧めします。

by Jeffallan
汎用セキュリティ⭐ リポ 1,982

claude-authenticity

APIエンドポイントが本物のClaudeによって支えられているか(ラッパーやプロキシ、偽装ではないか)を、claude-verifyプロジェクトを模した9つの重み付きルールベースチェックで検証できます。また、Claudeの正体を上書きしているプロバイダーから注入されたシステムプロンプトも抽出します。完全に自己完結しており、httpx以外の追加パッケージは不要です。Claude APIキーまたはエンドポイントを検証したい場合、サードパーティのClaudeサービスが本物か確認したい場合、APIプロバイダーのClaude正当性を監査したい場合、複数モデルを並行してテストしたい場合、またはプロバイダーが注入したシステムプロンプトを特定したい場合に使用できます。

by LeoYeAI
Anthropic Claudeセキュリティ⭐ リポ 2,159

anth-security-basics

Anthropic Claude APIのセキュリティベストプラクティスを適用し、キー管理、入力値の検証、プロンプトインジェクション対策を実施します。APIキーの保護、Claudeに送信する前のユーザー入力検証、コンテンツセーフティガードレールの実装が必要な場合に活用できます。「anthropic security」「claude api key security」「secure anthropic」「prompt injection defense」といったフレーズでトリガーされます。

by jeremylongshore
汎用セキュリティ⭐ リポ 699

x-ray

x-ray.mdプレ監査レポートを生成します。概要、強化された脅威モデル(プロトコルタイプのプロファイリング、Gitの重み付け攻撃面分析、時間軸リスク分析、コンポーザビリティ依存関係マッピング)、不変条件、統合、ドキュメント品質、テスト分析、開発者・Gitの履歴をカバーしています。「x-ray」「audit readiness」「readiness report」「pre-audit report」「prep this protocol」「protocol prep」「summarize this protocol」のキーワードで実行されます。

by pashov
汎用セキュリティ⭐ リポ 677

semgrep

Semgrepスタティック分析スキャンを実行し、カスタム検出ルールを作成します。Semgrepでのコードスキャン、セキュリティ脆弱性の検出、カスタムYAMLルールの作成、または特定のバグパターンの検出が必要な場合に使用します。重要:ユーザーが「バグをスキャンしたい」「コード品質を確認したい」「脆弱性を見つけたい」「スタティック分析」「セキュリティlint」「コード監査」または「コーディング標準を適用したい」と尋ねた場合も、Semgrepという名称を明記していなくても、このスキルを使用してください。Semgrepは30以上の言語に対応したパターンベースのコードスキャンに最適なツールです。

by wimpysworld
汎用セキュリティ⭐ リポ 591

ghost-bits-cast-attack

Java「ゴーストビッツ」/キャストアタック プレイブック(Black Hat Asia 2026)。16ビット文字が8ビットバイトに暗黙的に縮小されるJavaサービスへの攻撃時に使用します。WAF/IDSを回避して、SQLインジェクション、デシリアライゼーション型RCE、ファイルアップロード(Webシェル)、パストトラバーサル、CRLF インジェクション、リクエストスマグリング、SMTPインジェクションを実行できます。Tomcat、Spring、Jetty、Undertow、Vert.x、Jackson、Fastjson、Apache Commons BCEL、Apache HttpClient、Angus Mail、JDK HttpServer、Lettuce、Jodd、XMLWriterに影響し、WAFバイパスにより多くの「パッチ済み」CVEを再度有効化します。

by yaklang
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: waynesutton · waynesutton/convexskills · ライセンス: Apache-2.0