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

clerk-security-basics

Clerk認証を使用してセキュリティベストプラクティスを実装できます。アプリケーションのセキュリティ強化、認証実装の確認、またはClerk設定のハードニングが必要な場合に使用します。「clerk security」「secure clerk」「clerk best practices」「clerk hardening」といったフレーズでトリガーできます。

description の原文を見る

Implement security best practices with Clerk authentication. Use when securing your application, reviewing auth implementation, or hardening Clerk configuration. Trigger with phrases like "clerk security", "secure clerk", "clerk best practices", "clerk hardening".

SKILL.md 本文

Clerk セキュリティの基本

概要

アプリケーションで Clerk 認証のセキュリティベストプラクティスを実装します。

前提条件

  • Clerk SDK がインストール・設定されていること
  • 認証セキュリティの概念を理解していること
  • 本番デプロイメントが計画されている、または運用中であること

手順

ステップ 1: 環境変数の保護

# .env.local (開発環境)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...

# .env.production (本番環境 - シークレットマネージャーを使用)
# 本番キーを Git にコミットしないでください
# Vercel/Railway/AWS Secrets Manager を使用してください

# .gitignore
.env.local
.env.production
.env*.local
// lib/env.ts - 起動時に環境変数を検証
const requiredEnvVars = [
  'NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY',
  'CLERK_SECRET_KEY'
]

export function validateEnv() {
  for (const envVar of requiredEnvVars) {
    if (!process.env[envVar]) {
      throw new Error(`Missing required environment variable: ${envVar}`)
    }
  }

  // キー形式を検証
  const pk = process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY!
  if (!pk.startsWith('pk_test_') && !pk.startsWith('pk_live_')) {
    throw new Error('Invalid publishable key format')
  }
}

ステップ 2: ミドルウェア設定の保護

// middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'

const isPublicRoute = createRouteMatcher([
  '/',
  '/sign-in(.*)',
  '/sign-up(.*)',
  '/api/webhooks(.*)'
])

const isAdminRoute = createRouteMatcher(['/admin(.*)'])
const isSensitiveRoute = createRouteMatcher(['/api/admin(.*)', '/api/billing(.*)'])

export default clerkMiddleware(async (auth, request) => {
  const { userId, orgRole } = await auth()

  // セキュリティヘッダー
  const response = NextResponse.next()
  response.headers.set('X-Frame-Options', 'DENY')
  response.headers.set('X-Content-Type-Options', 'nosniff')
  response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')

  // ルートの保護
  if (!isPublicRoute(request)) {
    if (!userId) {
      return NextResponse.redirect(new URL('/sign-in', request.url))
    }
  }

  // 管理ルートは管理者ロールが必須
  if (isAdminRoute(request) && orgRole !== 'org:admin') {
    return NextResponse.redirect(new URL('/unauthorized', request.url))
  }

  // 機密ルートへのアクセスをログ出力
  if (isSensitiveRoute(request)) {
    console.log('Sensitive route accessed:', {
      path: request.nextUrl.pathname,
      userId,
      timestamp: new Date().toISOString()
    })
  }

  return response
})

ステップ 3: API ルートの保護

// app/api/protected/route.ts
import { auth } from '@clerk/nextjs/server'
import { headers } from 'next/headers'

export async function POST(request: Request) {
  // 1. 認証を検証
  const { userId, sessionId } = await auth()
  if (!userId) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 })
  }

  // 2. リクエストオリジンを検証 (CSRF 対策)
  const headersList = await headers()
  const origin = headersList.get('origin')
  const allowedOrigins = [
    process.env.NEXT_PUBLIC_APP_URL,
    'https://yourdomain.com'
  ]

  if (origin && !allowedOrigins.includes(origin)) {
    return Response.json({ error: 'Invalid origin' }, { status: 403 })
  }

  // 3. コンテンツタイプを検証
  const contentType = headersList.get('content-type')
  if (!contentType?.includes('application/json')) {
    return Response.json({ error: 'Invalid content type' }, { status: 400 })
  }

  // 4. ボディをパースして検証
  let body
  try {
    body = await request.json()
  } catch {
    return Response.json({ error: 'Invalid JSON' }, { status: 400 })
  }

  // 5. リクエストを処理
  return Response.json({ success: true })
}

ステップ 4: Webhook 処理の保護

// app/api/webhooks/clerk/route.ts
import { Webhook } from 'svix'
import { headers } from 'next/headers'
import { WebhookEvent } from '@clerk/nextjs/server'

export async function POST(req: Request) {
  const WEBHOOK_SECRET = process.env.CLERK_WEBHOOK_SECRET

  if (!WEBHOOK_SECRET) {
    console.error('CLERK_WEBHOOK_SECRET not configured')
    return Response.json({ error: 'Configuration error' }, { status: 500 })
  }

  // ヘッダーを取得
  const headerPayload = await headers()
  const svix_id = headerPayload.get('svix-id')
  const svix_timestamp = headerPayload.get('svix-timestamp')
  const svix_signature = headerPayload.get('svix-signature')

  // 必須ヘッダーを検証
  if (!svix_id || !svix_timestamp || !svix_signature) {
    return Response.json({ error: 'Missing svix headers' }, { status: 400 })
  }

  // Webhook を検証
  const body = await req.text()
  const wh = new Webhook(WEBHOOK_SECRET)

  let evt: WebhookEvent

  try {
    evt = wh.verify(body, {
      'svix-id': svix_id,
      'svix-timestamp': svix_timestamp,
      'svix-signature': svix_signature
    }) as WebhookEvent
  } catch (err) {
    console.error('Webhook verification failed:', err)
    return Response.json({ error: 'Invalid signature' }, { status: 400 })
  }

  // 検証済みイベントを処理
  const eventType = evt.type

  // べき等性チェック (リプレイ攻撃を防止)
  const processed = await checkIfProcessed(svix_id)
  if (processed) {
    return Response.json({ message: 'Already processed' })
  }

  // イベントを処理
  await processWebhookEvent(evt)

  // 処理済みとしてマーク
  await markAsProcessed(svix_id)

  return Response.json({ success: true })
}

ステップ 5: セッションセキュリティ

// lib/session-security.ts
import { auth } from '@clerk/nextjs/server'

export async function validateSession() {
  const { userId, sessionClaims } = await auth()

  if (!userId) {
    throw new Error('No session')
  }

  // セッション年齢をチェック
  const issuedAt = sessionClaims?.iat
  const maxAge = 60 * 60 // 1 時間(秒単位)

  if (issuedAt && Date.now() / 1000 - issuedAt > maxAge) {
    throw new Error('Session too old, please re-authenticate')
  }

  return { userId, sessionClaims }
}

// 機密操作では新しい認証を強制
export async function requireFreshAuth() {
  const { userId, sessionClaims } = await auth()

  if (!userId) {
    throw new Error('Not authenticated')
  }

  const issuedAt = sessionClaims?.iat
  const freshThreshold = 5 * 60 // 5 分

  if (issuedAt && Date.now() / 1000 - issuedAt > freshThreshold) {
    throw new Error('Please re-authenticate for this action')
  }

  return { userId }
}

出力

  • セキュアな環境設定
  • 強化されたミドルウェア
  • 保護された API ルート
  • 検証済みの Webhook 処理

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

  • 本番キーをシークレットマネージャーに保存
  • 環境変数を起動時に検証
  • ミドルウェアがすべての機密ルートを保護
  • API ルートが認証を検証
  • Webhook が svix で検証される
  • セキュリティヘッダーが設定されている
  • 本番環境で HTTPS が強制される
  • セッションタイムアウトが設定されている

リソース

次のステップ

本番環境への準備状況を確認するため、clerk-prod-checklist に進みます。

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

詳細情報

作者
Brmbobo
リポジトリ
Brmbobo/Web2podcast
ライセンス
MIT
最終更新
2026/1/26

Source: https://github.com/Brmbobo/Web2podcast / ライセンス: MIT

関連スキル

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 フォームよりご連絡ください。
原作者: Brmbobo · Brmbobo/Web2podcast · ライセンス: MIT