security
OWASPセキュリティパターンの適用、シークレット管理、セキュリティテストに関するスキル。脆弱性対策やセキュアなコード設計が必要な場面で活用できます。
description の原文を見る
OWASP security patterns, secrets management, security testing
SKILL.md 本文
セキュリティスキル
すべてのプロジェクトにおけるセキュリティベストプラクティスと自動セキュリティテスト。
コア原則
セキュリティはオプションではありません。 すべてのプロジェクトはマージ前にセキュリティチェックに合格する必要があります。すべての入力は悪意あるものと想定し、すべてのシークレットがコミットされたら漏洩すると考え、すべての依存関係に脆弱性があると仮定してください。
必須セキュリティ設定
1. Gitignore(非交渉)
すべてのプロジェクトは .gitignore にこれらを含める必要があります:
# Environment files - NEVER commit
.env
.env.*
!.env.example
# Secrets
*.pem
*.key
*.p12
*.pfx
credentials.json
secrets.json
*-credentials.json
service-account*.json
# IDE and OS
.idea/
.vscode/settings.json
.DS_Store
Thumbs.db
# Dependencies
node_modules/
__pycache__/
*.pyc
.venv/
venv/
# Build outputs
dist/
build/
*.egg-info/
# Logs that might contain sensitive data
*.log
logs/
2. 環境変数
.env.example を作成して、すべての必須変数を値なしで記載します:
# .env.example - Copy to .env and fill in values
# Server-side only (NEVER prefix with VITE_ or NEXT_PUBLIC_)
DATABASE_URL=
ANTHROPIC_API_KEY=
SUPABASE_SERVICE_ROLE_KEY=
# Client-side safe (public, non-sensitive)
VITE_SUPABASE_URL=
VITE_SUPABASE_ANON_KEY=
フロントエンド環境変数(重要!)
シークレットをクライアント公開環境変数に入れることは絶対禁止:
| フレームワーク | クライアント公開プレフィックス | サーバーのみ |
|---|---|---|
| Vite | VITE_* | プレフィックスなし |
| Next.js | NEXT_PUBLIC_* | プレフィックスなし |
| Create React App | REACT_APP_* | N/A(サーバーなし) |
// 間違い - シークレットがブラウザバンドルに公開される!
const apiKey = import.meta.env.VITE_ANTHROPIC_API_KEY;
// 正解 - クライアント側は公開値のみ
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
// 正解 - シークレットはサーバー側のみ
// API ルートまたはサーバー関数内:
const apiKey = process.env.ANTHROPIC_API_KEY;
Vercel 環境変数:
- Vercel ダッシュボードでは、
VITE_プレフィックスなしのシークレットはサーバーのみ VITE_*変数のみがクライアントコードにバンドルされる- ブラウザの devtools → Sources → バンドルでシークレットが公開されていないことを常に確認
スタートアップ時に環境を検証:
// config/env.ts
import { z } from 'zod';
const envSchema = z.object({
DATABASE_URL: z.string().url(),
ANTHROPIC_API_KEY: z.string().min(1),
NODE_ENV: z.enum(['development', 'production', 'test']),
});
export const env = envSchema.parse(process.env);
# config/env.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
anthropic_api_key: str
environment: str = "development"
class Config:
env_file = ".env"
settings = Settings()
セキュリティテスト
コミット前セキュリティチェック
pre-commit フックに追加:
すべてのプロジェクト対象:
# .pre-commit-config.yaml (既存に追加)
repos:
# Detect secrets
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
# Check for security issues in dependencies
- repo: local
hooks:
- id: security-check
name: security-check
entry: ./scripts/security-check.sh
language: script
pass_filenames: false
TypeScript/JavaScript:
// package.json scripts
{
"scripts": {
"security:audit": "npm audit --audit-level=high",
"security:secrets": "npx secretlint '**/*'",
"security:deps": "npx better-npm-audit audit"
}
}
Python:
# 開発依存関係に追加
pip install safety bandit
# コマンド
safety check # Check dependencies for vulnerabilities
bandit -r src/ # Static security analysis
セキュリティチェックスクリプト
scripts/security-check.sh を作成:
#!/bin/bash
set -e
echo "Running security checks..."
# Check for secrets in staged files
echo "Checking for secrets..."
if command -v detect-secrets &> /dev/null; then
detect-secrets scan --baseline .secrets.baseline
fi
# Check .env is not staged
if git diff --cached --name-only | grep -E '^\.env$|^\.env\.' | grep -v '\.example$'; then
echo "ERROR: .env file is staged for commit!"
exit 1
fi
# Check for common secret patterns in staged files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
if echo "$STAGED_FILES" | xargs grep -l -E '(password|secret|api_key|apikey|token|private_key)\s*[:=]\s*["\047][^"\047]+["\047]' 2>/dev/null; then
echo "ERROR: Possible secrets found in staged files!"
exit 1
fi
# Language-specific checks
if [ -f "package.json" ]; then
echo "Checking npm dependencies..."
npm audit --audit-level=high || echo "Warning: npm audit found issues"
fi
if [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then
echo "Checking Python dependencies..."
if command -v safety &> /dev/null; then
safety check || echo "Warning: safety found issues"
fi
fi
echo "Security checks passed!"
chmod +x scripts/security-check.sh
GitHub Actions セキュリティワークフロー
.github/workflows/security.yml を作成:
name: Security
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# Run weekly on Monday at 9am UTC
- cron: '0 9 * * 1'
jobs:
secrets-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect secrets
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.event.pull_request.head.sha }}
dependency-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Node.js projects
- name: Setup Node
if: hashFiles('package.json') != ''
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
if: hashFiles('package.json') != ''
run: npm ci
- name: NPM Audit
if: hashFiles('package.json') != ''
run: npm audit --audit-level=high
# Python projects
- name: Setup Python
if: hashFiles('pyproject.toml') != '' || hashFiles('requirements.txt') != ''
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install safety
if: hashFiles('pyproject.toml') != '' || hashFiles('requirements.txt') != ''
run: pip install safety
- name: Safety check
if: hashFiles('pyproject.toml') != '' || hashFiles('requirements.txt') != ''
run: safety check
codeql:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ hashFiles('package.json') != '' && 'javascript-typescript' || 'python' }}
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
入力検証(OWASP Top 10)
1. SQLインジェクション対策
文字列連結は絶対禁止:
// 悪い例 - SQL インジェクション脆弱性あり
const user = await db.query(`SELECT * FROM users WHERE id = ${userId}`);
// 良い例 - パラメータ化クエリ
const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
// 良い例 - ORM 使用(Kysely、Prisma、Drizzle)
const user = await db.selectFrom('users').where('id', '=', userId).execute();
# 悪い例 - SQL インジェクション脆弱性あり
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
# 良い例 - パラメータ化クエリ
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# 良い例 - ORM 使用(SQLAlchemy)
user = session.query(User).filter(User.id == user_id).first()
2. XSS 対策
// ユーザー入力をレンダリング前に必ずサニタイズ
import DOMPurify from 'dompurify';
// 悪い例 - XSS 脆弱性あり
element.innerHTML = userInput;
// 良い例 - サニタイズ済み
element.innerHTML = DOMPurify.sanitize(userInput);
// ベスト - フレームワークの組み込みエスケープを使用(React はデフォルトで対応)
return <div>{userInput}</div>; // Safe in React
// 危険 - React の保護を回避
return <div dangerouslySetInnerHTML={{ __html: userInput }} />; // 避けること!
3. 入力検証(境界)
// Zod ですべての外部入力を検証
import { z } from 'zod';
const CreateUserSchema = z.object({
email: z.string().email().max(255),
name: z.string().min(1).max(100).regex(/^[a-zA-Z\s]+$/),
age: z.number().int().min(0).max(150),
});
// ルートハンドラ内
app.post('/users', async (req, res) => {
const result = CreateUserSchema.safeParse(req.body);
if (!result.success) {
return res.status(400).json({ error: result.error });
}
// result.data は型付けされ検証済み
});
4. パストトラバーサル対策
import path from 'path';
// 悪い例 - パストトラバーサル脆弱性あり
const filePath = `./uploads/${req.params.filename}`;
// 良い例 - パスを検証&サニタイズ
const filename = path.basename(req.params.filename); // ../ を削除
const filePath = path.join('./uploads', filename);
// 許可ディレクトリ内にあることを確認
if (!filePath.startsWith(path.resolve('./uploads'))) {
throw new Error('Invalid path');
}
認証・認可
JWT ベストプラクティス
import jwt from 'jsonwebtoken';
// トークン生成
function generateToken(userId: string): string {
return jwt.sign(
{ sub: userId },
process.env.JWT_SECRET!,
{
expiresIn: '15m', // 短命なアクセストークン
algorithm: 'HS256',
}
);
}
// トークン検証
function verifyToken(token: string): { sub: string } {
return jwt.verify(token, process.env.JWT_SECRET!, {
algorithms: ['HS256'], // 明示的に許可アルゴリズムを指定
}) as { sub: string };
}
パスワードハッシング
import bcrypt from 'bcrypt';
const SALT_ROUNDS = 12; // 最小 10、推奨 12 以上
async function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, SALT_ROUNDS);
}
async function verifyPassword(password: string, hash: string): Promise<boolean> {
return bcrypt.compare(password, hash);
}
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def hash_password(password: str) -> str:
return pwd_context.hash(password)
def verify_password(password: str, hashed: str) -> bool:
return pwd_context.verify(password, hashed)
レート制限
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分
max: 100, // ウィンドウあたり100リクエスト
standardHeaders: true,
legacyHeaders: false,
});
// 認証ルートに適用
app.use('/api/auth', rateLimit({
windowMs: 60 * 1000, // 1分
max: 5, // 1分あたり5試行
message: 'Too many login attempts, please try again later',
}));
セキュリティヘッダ
import helmet from 'helmet';
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
},
}));
セキュリティテストチェックリスト
すべてのリリース前に実行:
## セキュリティチェックリスト
### シークレット&環境変数
- [ ] コードにシークレットがない(detect-secrets を実行)
- [ ] .env ファイルが .gitignore に含まれている
- [ ] .env.example が存在し、すべての必須変数が記載されている
- [ ] スタートアップ時に環境を検証
### 依存関係
- [ ] npm audit / safety check に合格
- [ ] 依存関係に既知の脆弱性がない
- [ ] 依存関係が最新(Dependabot 有効)
### 入力検証
- [ ] すべての API 入力を Zod/Pydantic で検証
- [ ] ファイルアップロードはタイプとサイズで制限
- [ ] パストトラバーサル対策
### 認証
- [ ] パスワードを bcrypt でハッシュ化(12 ラウンド以上)
- [ ] JWT は短い有効期限を使用
- [ ] 認証エンドポイントにレート制限
- [ ] ログイン時にセッショントークンをローテーション
### データベース
- [ ] パラメータ化クエリのみ使用
- [ ] データベースユーザーは最小権限
- [ ] 接続文字列がログに記録されない
### ヘッダ&CORS
- [ ] セキュリティヘッダが有効(helmet)
- [ ] CORS は既知のオリジンのみ許可
- [ ] 本番環境では HTTPS のみ
### ログ
- [ ] ログにシークレットが含まれない
- [ ] ログに個人情報が含まれない(またはマスク済み)
- [ ] 認証失敗をログに記録
セキュリティアンチパターン
- ❌
VITE_*、NEXT_PUBLIC_*、REACT_APP_*環境変数にシークレット(クライアント公開!) - ❌ コードまたはコミット済みの config ファイルにシークレット
- ❌ .env ファイルの .gitignore エントリなし
- ❌ SQL クエリに文字列連結
- ❌ サニタイズなしの
dangerouslySetInnerHTML - ❌ ユーザー入力で
eval()またはnew Function() - ❌ パスワードをプレーンテキストまたは弱いハッシュ(MD5、SHA1)で保存
- ❌ 有効期限なしまたは非常に長い有効期限の JWT
- ❌ 認証エンドポイントにレート制限なし
- ❌ ログに機密データ(パスワード、トークン、個人情報)を記録
- ❌ 本番環境で CORS オリジンに
*を使用 - ❌ npm audit / safety check の警告を無視
- ❌ 本番環境で root / admin として実行
- ❌ どの環境にもハードコードされた認証情報
- ❌ SSL/TLS 検証を無効化
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- alinaqi
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/alinaqi/claude-bootstrap / ライセンス: MIT
関連スキル
secure-code-guardian
認証・認可の実装、ユーザー入力の保護、OWASP Top 10の脆弱性対策が必要な場合に使用します。bcrypt/argon2によるパスワードハッシング、パラメータ化ステートメントによるSQLインジェクション対策、CORS/CSPヘッダーの設定、Zodによる入力検証、JWTトークンの構築などのカスタムセキュリティ実装に対応します。認証、認可、入力検証、暗号化、OWASP Top 10対策、セッション管理、セキュリティ強化全般で活用できます。ただし、構築済みのOAuth/SSO統合や単独のセキュリティ監査が必要な場合は、より特化したスキルの検討をお勧めします。
claude-authenticity
APIエンドポイントが本物のClaudeによって支えられているか(ラッパーやプロキシ、偽装ではないか)を、claude-verifyプロジェクトを模した9つの重み付きルールベースチェックで検証できます。また、Claudeの正体を上書きしているプロバイダーから注入されたシステムプロンプトも抽出します。完全に自己完結しており、httpx以外の追加パッケージは不要です。Claude APIキーまたはエンドポイントを検証したい場合、サードパーティのClaudeサービスが本物か確認したい場合、APIプロバイダーのClaude正当性を監査したい場合、複数モデルを並行してテストしたい場合、またはプロバイダーが注入したシステムプロンプトを特定したい場合に使用できます。
anth-security-basics
Anthropic Claude APIのセキュリティベストプラクティスを適用し、キー管理、入力値の検証、プロンプトインジェクション対策を実施します。APIキーの保護、Claudeに送信する前のユーザー入力検証、コンテンツセーフティガードレールの実装が必要な場合に活用できます。「anthropic security」「claude api key security」「secure anthropic」「prompt injection defense」といったフレーズでトリガーされます。
x-ray
x-ray.mdプレ監査レポートを生成します。概要、強化された脅威モデル(プロトコルタイプのプロファイリング、Gitの重み付け攻撃面分析、時間軸リスク分析、コンポーザビリティ依存関係マッピング)、不変条件、統合、ドキュメント品質、テスト分析、開発者・Gitの履歴をカバーしています。「x-ray」「audit readiness」「readiness report」「pre-audit report」「prep this protocol」「protocol prep」「summarize this protocol」のキーワードで実行されます。
semgrep
Semgrepスタティック分析スキャンを実行し、カスタム検出ルールを作成します。Semgrepでのコードスキャン、セキュリティ脆弱性の検出、カスタムYAMLルールの作成、または特定のバグパターンの検出が必要な場合に使用します。重要:ユーザーが「バグをスキャンしたい」「コード品質を確認したい」「脆弱性を見つけたい」「スタティック分析」「セキュリティlint」「コード監査」または「コーディング標準を適用したい」と尋ねた場合も、Semgrepという名称を明記していなくても、このスキルを使用してください。Semgrepは30以上の言語に対応したパターンベースのコードスキャンに最適なツールです。
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を再度有効化します。