
Next.js、Supabase、Stripeアプリ向けのローカル静的セキュリティスキャナー:キー漏洩、RLSと権限付与の欠落、安全でないWebhookを検出する24のASTベースチェック。CLIとGitHub Action。
Next.js + Supabase + Stripe アプリ向けの無料ローカルセキュリティスキャン:漏洩したキー、欠落した RLS とグラント、安全でない Stripe Webhook を検出。
あなたの AI エージェントはアプリを出荷しました。しかし、Stripe のシークレットキーや、RLS のないテーブル、誰でも呼び出せる Webhook まで一緒に出荷していませんか? コマンド1つで、ローカルで、1秒未満で判明します。
npx github:edtrackai/nextjs-supabase-stripe-security-checker /path/to/your/app
まだnpmには公開されていないため、npxでこのGitHubリポジトリから直接実行します(Node 18+とgitが必要です)。
- uses: edtrackai/nextjs-supabase-stripe-security-checker@v0
with:
fail-on: high
完全なワークフローと権限は以下および docs/github-action.md に記載されています。
Supabase RLS チェッカー · Stripe webhook セキュリティ · Next.js セキュリティスキャン · Supabase Data API グラント (42501)

git clone https://github.com/edtrackai/nextjs-supabase-stripe-security-checker.git
cd nextjs-supabase-stripe-security-checker && npm install
node bin/nss-security-check.js /path/to/your/app
Node 18 以降が必要です。依存関係は 1 つ(@babel/parser)だけです。無料で MIT ライセンス、アカウント不要、ネットワーク呼び出しを行わず、コードをアップロードすることもありません。
--fail-on=high で終了コード 1 になり、--json で機械可読な出力が得られます。広告(有料、同一作者): 修正方法をお探しですか? Launch Audit(該当する場合は 12 ドル+VAT)では、28 個のチェック、Edit や Write ツールを持たない AI 監査エージェント、file:line 形式の修正計画を提供します。
| フラグ | 動作 |
|---|---|
--json | 機械可読な出力: {tool, version, root, filesScanned, counts, findings[]} |
--fail-on=<sev> | critical / high / medium / low 以上の検出結果が 1 件でもあれば終了コード 1(none は決して失敗しません)。不正な引数の場合は終了コード 2。 |
--list | チェックカタログを出力 |
--quiet | 有料ツールに関する 1 行のフッターを省略(ターミナル上でのみ stderr に出力。NO_PROMO=1、CI、GITHUB_ACTIONS でも無効化) |
--help | 使用方法 |
CI での実行: node path/to/bin/nss-security-check.js . --fail-on=high、または GitHub Action を使用します(ジョブサマリー、アノテーション、1 つの固定 PR コメント、GITHUB_TOKEN のみ)。ワークフローの例と権限については docs/github-action.md を参照してください。
# .github/workflows/security-check.yml
name: Security check
on: [pull_request]
permissions:
contents: read
pull-requests: write # only for the PR comment; drop it with comment: false
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: edtrackai/nextjs-supabase-stripe-security-checker@v0 # or pin @v0.5.0 / a commit SHA
with:
path: .
fail-on: high
変更点は CHANGELOG.md に記載されています(0.5.0 で Action が追加されました)。
| ID | 重大度 | 領域 | チェック内容 |
|---|---|---|---|
| K1 | critical | キー | ソース内の本番用 Stripe シークレットキー/制限付きキー(sk_live_/rk_live_)。+ で分割されたキーも含む(証拠は伏字化される) |
| K2 | critical | キー | シークレットに見える NEXT_PUBLIC_ 変数(サービスロール、シークレットキー、Webhook シークレットなど) |
| K3 | critical | キー | 値が git で追跡されている .env ファイル |
| K4 | critical | キー | "use client" コンポーネント内で使用されているサーバーシークレットまたは Supabase 管理クライアント |
| A1 | high | 認証 | サーバー上で getUser()/getClaims() ではなく auth.getSession() を信頼している |
| A2 | high | 認証 | 認証チェックなしでデータを書き込む Server Action |
| A3 | high | 認証 | 認証チェックなしでデータを書き込む API ルート(POST/PUT/PATCH/DELETE)(Webhook、cron、認証ルートは除外) |
| A4 | high | 認証 | リクエストで指定された id を所有者フィルターなしで管理クライアントに問い合わせている(IDOR) |
| A5 | medium | 認証 | クエリパラメータによるオープンリダイレクト |
| R1 | critical | RLS | 行レベルセキュリティなしで作成されたテーブル |
| R2 | critical | RLS | using (true) / with check (true) を含む書き込みポリシー |
| R3 | high | RLS | anon ロールに書き込みを許可するポリシー |
| R4 | high | RLS | search_path が固定されていない security definer 関数 |
| R5 | medium | RLS | 明示的な GRANT がない public 内のテーブル。Supabase は 2026年10月30日から新しい public テーブルへのデフォルト付与を停止すると発表しましたが、8月下旬に Supabase CLI のメンテナーが(supabase/cli PR #6337 で)以前のデフォルト変更は「実現しなかった」と書き、ホスト型プロジェクトでは依然として自動付与が行われていたため、この日付は変わる可能性があります。ご自身のプロジェクトの挙動を確認してください。付与がない場合、Data API は 42501 を返します |
| R6 | high | RLS | anon/authenticated への包括的な grant ... on all tables in schema public / alter default privileges ... grant(42501 の手っ取り早い修正ですが、RLS のないテーブルも露出させてしまいます) |
| S1 | critical | Stripe | 署名検証(constructEvent)なしの Webhook |
| S2 | critical | Stripe | 生のボディではなく request.json() をパースする Webhook |
| S3 | medium | Stripe | event.id に対する冪等性がない Webhook |
| S4 | high | Stripe | リクエストから取得した Checkout の価格または金額 |
| S5 | high | Stripe | Webhook 内ではなく Checkout 成功ページでアクセスを許可している |
| S6 | medium | Stripe | 失敗したイベントを飲み込む可能性のある Webhook の重複排除:pending/completed ステータスなしで重複をスキップしている |
| S7 | low | Stripe | items.data[0] から読み取った請求期間(API 2025-03-31.basil 以降、複数アイテムのサブスクリプションでは誤り) |
| H1 | medium | ハードニング | next.config にセキュリティヘッダーがない |
| H2 | medium | ハードニング | リテラルでない値を持つ dangerouslySetInnerHTML |
fixtures/vulnerable-app は 23 個のファイルベースのチェックすべてをトリガーし、テストはそれぞれが期待されるファイルで検出されることを検証します。K3 は一時的な git リポジトリでテストされます。fixtures/clean-app(ハードニングされたリファレンスアプリ)と fixtures/near-miss(各ミスに見える安全なコード:pending/completed の冪等性を備えた生ボディ Webhook、複数アイテムに対応した安全な期間ルックアップ、ガードされたリダイレクト、所有者でフィルターされた管理クエリ、select using (true)、JSON-LD)は 0 件の検出結果を生成しなければなりません。npm test は CLI フラグと終了コードを含む node:test スイートを実行します。npm run smoke は 1 行のサマリーを出力します。requireUser*、getUser*、verifySession*、assertAuth*、auth()、currentUser()、protect() といった名前のヘルパーは認識されます。supabase/migrations と .sql ファイル内のSQLのみを読み取ります。ダッシュボードで作成されたポリシーは認識されません。npm audit を使用)、シークレットに関する完全なgit履歴(gitleaksを使用)はチェックしません。広告: 以下の製品は同じ作者(Stack & Ship)による有料製品です。CLIはどちらの場合も無料かつMITライセンスのままです。
この無料CLIは小さなサブセットです。ローンチを控えているなら: