db-security-access について
db-security-accessは、アクセス制御とデータ保護を確認するデータベースセキュリティ監査スキルです。RLS、PII、平文の認証情報、通信暗号化設定、SQLインジェクションの可能性を調べ、実行時検証が必要な項目も示します。
主な機能
- 01テナントテーブルのRLS状態確認
- 02保護されていない個人情報の特定
- 03平文の認証情報や秘密情報の検出
- 04接続のTLS設定確認
- 05ユーザー入力を連結したSQLの検出
活用シーン
- 01テナントテーブルの行レベル制御を監査
- 02スキーマやマイグレーションの認証情報を確認
- 03接続設定で無効化されたTLSを発見
- 04ORMソースのSQL連結を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hainrixz/ claude-db --skill db-security-accessインストール後、Claude Code で/db-security-accessを入力して読み込まれたか確認します。
詳細
db-security-access (M10)
セキュリティは 設計と完全性(軸 design)に関する懸念事項です。スキーマが完全に正規化されていても、すべての行が漏えいする可能性があります。このモジュールでは、誰がデータを読み書きできるか、またデータ自体が保存時および転送中に保護されているかを確認します。依存先であるマルチテナント/Supabase テーブルで RLS が無効になっている場合や、シークレットが平文で保存されている場合、SQL インジェクションがある場合は、重大度 5 の上限が適用されます。
チェック内容
- 行レベルセキュリティ(RLS) — Postgres/Supabase で、テナント単位またはユーザー単位の行を保持し、スーパーユーザー以外の/
anon/authenticatedロールからアクセスされるテーブルで RLS が有効になっていますか?このようなテーブルで RLS が無効の場合、severity:5、failとなります。(テナントの分離ロジックは M9 の担当です。M10 はオン/オフ状態を担当します。) - PII の露出 — 個人データを示唆する名前/型(email、ssn、phone、dob、address、
card/pan)の列が、暗号化/トークン化されずに保存またはログ記録されていませんか? - スキーマ内のシークレットの平文保存 — パスワード、API キー、トークンが、ハッシュ化に関する注記なしで
text/varcharとして保存されていませんか。または、DDL/マイグレーション/デフォルト値に認証情報がリテラルとして埋め込まれていませんか。severity:5です。 - 転送中の暗号化 —
sslmode=disableを強制する接続設定(またはリモートホストで TLS がない場合)はseverity:4です。保存時の暗号化がないことは、静的に判別できる場合にフラグを立てます。 - SQL インジェクション — ユーザー入力を使って SQL を組み立てる、生の文字列連結/f 文字列/テンプレートリテラル(ORM ソースまたはマイグレーションヘルパーから確認可能なもの)。
severity:5、designです。
スコア/軸
design のみに反映します(カテゴリ セキュリティ、M9/M20/M21 と共有するリレーショナルの重み 14。すべての NoSQL プロファイルにも同等の セキュリティ カテゴリがあります)。
Tier-0(静的)
DDL/マイグレーション/ORM ソースと接続設定を解析し、text 型のシークレット列、リテラルの認証情報(redactSecrets() と照合)、sslmode=disable、生の文字列連結による SQL、PII を示す名前の列を検出します。RLS の有効化(ALTER TABLE … ENABLE ROW LEVEL SECURITY)は宣言型 DDL から検出できます。ファイルから RLS の状態を確認できない場合は needs_api とします(暗黙の合格にはしません)。
Tier-1(検証クエリ、Postgres)
SELECT c.relname,
c.relrowsecurity AS rls_enabled,
c.relforcerowsecurity AS rls_forced,
(SELECT count(*) FROM pg_policies p WHERE p.tablename = c.relname) AS policy_count
FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public' AND c.relkind = 'r';
メソッド schema_introspect/constraint_check。テナント/ユーザーの行を保持するテーブルで rls_enabled = false の場合、M10.rls.* を established として確認し、上限を適用します。実行時にしか確認できないチェック(実際の保存時暗号化、ライブ TLS ネゴシエーション)は、Tier-0 では needs_api です。
検出結果
schema/finding.schema.json に従って検出結果を出力します。例:
M10.tenants.rls_disabled— テナント単位のテーブルで RLS が無効(severity:5、fail、軸design、Tier-1 では信頼度established/DDL からはdirectional、fixable: proposed)。M10.users.password_plaintext— ハッシュ化されずにシークレットがtextとして保存(severity:5、fail、established、fixable: advisory)。M10.conn.sslmode_disable— リモートホストでsslmode=disable(severity:4、warn、fixable: proposed)。M10.repo.sql_string_concat— ユーザー入力が SQL に連結されている(ソースからseverity:5、fail、directional、fixable: advisory)。
各検出結果では、evidence.observed にシークレットを秘匿したうえで、該当する DDL/接続行/クエリを原文のまま引用します。verification.reproduce は、上記のカタログクエリ($DATABASE_URL を参照)または該当パターンの grep とします。expected_impact は信頼度タグ付きの段階表記にします(単独のパーセンテージは禁止)。
誠実性
- 「PII が存在する」だけで自動的に不合格とはしません。フラグを立てるのは保護されていない PII です。多くの列では、正当に平文で保存されています。削除ではなく、暗号化/トークン化を推奨してください。
- 保存時の暗号化は通常、ファイルから確認できないプラットフォーム設定(クラウド KMS/ボリューム)です。
needs_apiと報告し、設定がないと断定しないでください。 - ソースのみから得た RLS/インジェクションの
directionalシグナルによって、重大度 5 の上限を適用することは決してありません。まず Tier-1 または生成された DDL で確認してください。