audit-security について
audit-securityは、アプリケーションコードのセキュリティ上の弱点を確認し、証拠のある問題を限定的にその場で修正するスキルです。入力から危険な処理箇所への流れを追って所見を記録し、認証に特化した確認は別のスキルに委ねます。
主な機能
- 01インジェクション、ヘッダー、依存関係の確認
- 02入力から危険な処理箇所への流れを追跡
- 03シークレットと依存関係のCVEをスキャン
- 04重大度と根拠を記録
- 05専門的な所見を別のスキルへ引き継ぎ
活用シーン
- 01リリース前のアプリケーション監査
- 02インジェクションやIDORの疑いを調査
- 03漏えいしたシークレットや依存リスクを確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kensaurus/ skills --skill audit-securityインストール後、Claude Code で/audit-securityを入力して読み込まれたか確認します。
詳細
セキュリティ監査スキル
自由度:混合 — ステップ 0~4 の判断は [自由度:高]、
依存関係とシークレットのスキャンは [自由度:低 — 正確に実行]。エクスプロイトの PoC は決して作成しないでください。
監査と修正の例外。 インラインで修正してもかまいません。計画のみのバーンダウン →
plan-security-audit。 インラインで修正する場合は、証拠のあるシンクだけをその場でパッチしてください。気づいた無関係の弱点は修正せず、検出事項としてレポートに記載してください。テストを追加するのは、リポジトリにセキュリティテストがすでにある場合、またはタスクで求められている場合に限ります。認証の動作、RLS、シークレットのローテーション、決済、マイグレーションは STOP して確認してください。
OWASP の静的レビュー(インジェクション、ヘッダー、依存関係)。セッション/ルート×ゲート/
getSession() → audit-auth-flows。Next.js 16 では middleware.ts と
proxy.ts を grep してください。ルートゲートはどちらのファイルにも存在する可能性があり、プロキシレイヤーには独自のバイパスクラスがあります。
推論の方法
- 観察 — シンクまたは不足しているチェックを引用します(
file:line) - 解釈 — 信頼されていない入力がクエリ、HTML、またはオブジェクト ID に到達し得るかを確認します
- 分類 — インジェクション/IDOR/シークレット/ヘッダー/依存関係の CVE/引き継ぎ
- 重大度 — 悪用可能なデータアクセスまたはハードコードされたシークレットは Critical です
実例
観察:
GET /documents/:idは ID のみで読み込みます(api/docs/route.ts:18)。 解釈: ルートにアクセスできるユーザーは、他のユーザーのドキュメントを読み取れます。 分類: IDOR。 重大度: Critical。 検出事項: IDOR |/documents/:id|userIdの条件を追加します。 このルートの Matcher/getSession()→audit-auth-flows。このチェックリストの対象ではありません。
ステップ 0:プロジェクトを理解する [自由度:高]
監査の前に、技術スタックと攻撃対象領域を調べます。
- 技術スタックを特定するため、
package.json/requirements.txt/go.modを読みます。
- 認証ライブラリ(next-auth、passport、supabase-auth、django-auth など)
- データベース ORM(Prisma、Sequelize、SQLAlchemy など)
- HTTP フレームワーク(Express、Fastify、Django、Flask など)
- セキュリティ固有のパッケージ(helmet、cors、csurf、rate-limit など)
- 認証パターンを特定します。
- セッションベース、JWT、OAuth のいずれか
- トークンの保存場所(Cookie、localStorage、ヘッダー)
- 権限/ロールの適用方法
- データフローを特定します。
- ユーザー入力がシステムに入る場所
- データの検証およびサニタイズ方法
- データがデータベースに到達する経路
ステップ 1:最新の脅威を調査する [自由度:高]
検出した技術スタックに関する最新の OWASP とセキュリティのベストプラクティスを取得します。
firecrawl:firecrawl_search
{
"query": "<framework> security best practices OWASP <current year>",
"limit": 5,
"sources": [{ "type": "web" }]
}
該当するプラットフォームの OWASP Top 10 をスクレイピングします。
firecrawl:firecrawl_scrape
{
"url": "https://owasp.org/Top10/",
"formats": ["markdown"],
"onlyMainContent": true
}
依存関係に既知の CVE がないかも確認します。
firecrawl:firecrawl_search
{
"query": "<package-name> CVE vulnerability <current year>",
"limit": 5,
"sources": [{ "type": "web" }]
}
ステップ 2:本番環境のセキュリティエラーを確認する(Sentry) [自由度:高]
Sentry が設定されている場合は、本番環境でセキュリティ関連のエラーを確認します。
sentry:search_issues
{
"organizationSlug": "<ORG_SLUG>",
"query": "401 unauthorized OR 403 forbidden OR CORS OR CSP violation in last 30 days",
"projectSlugOrId": "<PROJECT_SLUG>",
"regionUrl": "<REGION_URL>",
"limit": 20
}
セキュリティ上の検出事項を示すパターン:
- 401/403 エラーが頻発する → 認証バイパスの試行の可能性
- 想定外のオリジンからの CORS エラー → CORS の設定ミス
- CSP 違反 → XSS の潜在的な攻撃経路
- レート制限エラー → ブルートフォース攻撃の可能性
ステップ 3:自動コードスキャン [自由度:高]
認証監査
- パスワードが bcrypt/argon2/scrypt でハッシュ化されている(パスワードには MD5/SHA1/SHA256 を使用しない)
- セッショントークンが暗号学的に安全な乱数で生成されている
- セッションが適切なタイミングで期限切れになる(アイドルタイムアウト+絶対タイムアウト)
- パスワードリセットトークンが一度だけ使用でき、有効期限が短い
- 機密性の高いアカウントで MFA を利用できる
- ログインのレート制限が実装されている
- 失敗が繰り返された後にアカウントがロックされる
- OAuth の state パラメーターが検証される(OAuth フローでの CSRF 対策)
- JWT シークレットが強固で、環境変数に保存されている(ハードコードされていない)
- JWT の有効期限が妥当である(アクセス:15min、リフレッシュ:7d)
認可監査
- すべての API エンドポイントで権限を確認している(認証だけでは不十分です)
- 所有権や権限を確認せずにオブジェクトを直接参照していない(IDOR)
- ロールベースのアクセス制御を API 層で適切に適用している(UI だけでは不十分です)
- 最小権限の原則に従っている
- 管理者機能に昇格した認証を要求している
- マルチテナントデータベースで行レベルセキュリティ(RLS)を有効にしている
- API キーの権限を必要最小限に制限している
入力検証監査
- すべてのユーザー入力をサーバー側で検証している(クライアント側の検証は UX のためだけです)
- クエリ、HTML、コマンドで使用する前に入力をサニタイズしている
- ファイルアップロードを検証している:タイプ(MIME タイプとマジックバイト)、サイズ、ファイル名
- JSON/XML の解析に深度とサイズの上限を設けている
- URL パラメーターをデコードして検証している
- 生の SQL 文字列連結を使用していない(パラメーター化クエリのみ)
- ユーザー入力に対して
eval()、Function()、innerHTMLを使用していない - DOMPurify なしで
dangerouslySetInnerHTMLを使用していない
データ保護監査
- 機密データを保存時に暗号化している
- TLS/HTTPS を必須にしている(HTTP へのフォールバックなし)
- シークレットをコード、git の履歴、ログに含めていない
- 適用される規制(GDPR、CCPA)に従って個人情報を取り扱っている
- データベース接続を暗号化している(SSL)
- API レスポンスから内部データ(スタックトレース、SQL エラー、ファイルパス)が漏れていない
- パスワードフィールドに
type="password"とautocomplete="new-password"を使用している
セキュリティヘッダー監査
-
Strict-Transport-Security(HSTS)の max-age を長く設定している -
Content-Security-Policy(CSP)を設定している(default-src *だけでは不十分です) -
X-Content-Type-Options: nosniff -
X-Frame-Options: DENYまたはSAMEORIGIN -
Referrer-Policy: strict-origin-when-cross-originまたはそれより厳しい設定 - 不要なブラウザー機能を制限する
Permissions-Policy - 認証が必要なエンドポイントで、CORS の
Access-Control-Allow-Originが*ではない - Cookie に
HttpOnly、Secure、SameSite=Strict(またはLax)を設定している
依存関係の監査 [自由度:低 — 指示どおりに実行]
npm audit # Node.js
pip-audit # Python
cargo audit # Rust
govulncheck ./... # Go
bundle audit # Ruby
- 既知の重大または深刻な CVE がない
- 依存関係を適切に最新の状態に保っている
- ロックファイルをコミットしている(
package-lock.json、yarn.lock、pnpm-lock.yaml) - 不要な依存関係がない(攻撃対象領域を縮小する)
ステップ 4:よくある脆弱性パターン [自由度:高]
脆弱性につながる処理を grep で検索し、該当箇所を文脈とともに確認します。
- SQL インジェクション — クエリへの文字列補間(
`SELECT … ${、+ userId +)。パラメーター化クエリまたは ORM の呼び出しは問題ありません - XSS — ユーザー入力を
DOMPurify.sanitizeなしでdangerouslySetInnerHTML/innerHTMLに渡している - IDOR —
req.params.idによる読み込みで、クエリに所有者の条件(userId: req.user.id)がない - 機密データの露出 — 明示的にフィールドを選択せず、
res.json(user)のようにレコード全体を返している
ステップ 5:環境とシークレット [自由度:低 — 名前/プレフィックスのみ]
ハードコードされたシークレットをスキャンする
コードベースを検索し、漏えいした可能性のあるシークレットを探します。検索するパターン:
- 一般的なシークレット名:
api_key、apiKey、secret、password、token、credentials、private_key - キーのプレフィックス:
sk-、pk-、ghp_、gho_、xox[bpsa]-、AKIA - 秘密鍵のヘッダー:
-----BEGIN (RSA|EC|OPENSSH) PRIVATE KEY-----
.gitignore を確認する
.env, .env.local, .env.production
*.pem, *.key, *.p12
credentials.json, service-account.json
.sentryclirc (if it contains auth tokens)
環境変数を検証する
import { z } from 'zod';
const envSchema = z.object({
DATABASE_URL: z.string().url(),
API_KEY: z.string().min(1),
JWT_SECRET: z.string().min(32),
SENTRY_DSN: z.string().url().optional(),
});
const env = envSchema.parse(process.env);
修正を適用する前の自己批評 [自由度:低 — 省略禁止]
- 証拠がある — 「インジェクションの可能性がある」ではなく、
file:lineまたは監査出力を示す - 再現可能である — 同じシンクが残っていることを確認する。エクスプロイトの PoC は作成しない
- 深刻度に根拠がある — Critical は、データアクセスまたはシークレットの漏えいが実証されている場合のみ
- 担当先が適切である — セッション/route×gate/
getSession→audit-auth-flows、RLS →plan-rls-audit、LLM →audit-llm-security - 誤った安全判断をしない — ヘッダーやミドルウェアだけでは認可にならない
出力:セキュリティ監査レポート
## Security Audit: [Project Name]
### Tech Stack
- Framework: [name + version]
- Auth: [library + pattern]
- Database: [ORM + provider]
- Security packages: [list]
### Critical Issues (must fix)
| # | Category | Finding | File | Recommendation |
|---|----------|---------|------|----------------|
| 1 | Auth | JWT secret hardcoded | config.ts:12 | Move to env var |
### High Risk (should fix soon)
| # | Category | Finding | File | Recommendation |
|---|----------|---------|------|----------------|
### Medium Risk (improve when possible)
| # | Category | Finding | File | Recommendation |
|---|----------|---------|------|----------------|
### Passed Checks
- [list of security areas that are properly implemented]
### Dependencies
- Critical CVEs: [count] — [details]
- High CVEs: [count]
- Outdated packages: [count]
### Research Sources
- [URL] — [what it confirmed or revealed]
セッション/route×gate/getSession() に関する検出事項は、この OWASP チェックリストではなく、
audit-auth-flows に記載してください。