なぜ危ないのか
Stripeのキーには2種類ある。`pk_`で始まる公開可能キー(Publishable Key)と、`sk_`で始まるシークレットキーだ。公開可能キーはフロントエンドのJavaScriptに含めることを前提に設計されているが、シークレットキーは絶対にHTMLやクライアントサイドのコードに含めてはならない。シークレットキーを持つ者はStripeアカウントで支払いの作成・払い戻し・顧客データの取得を実行できるため、漏えいすると直接的な金銭的被害につながる。
AIは決済の流れを全部HTMLに実装しようとするとき、本来サーバーサイドで処理すべき支払いインテント作成のコードをJavaScriptとして書き、シークレットキーを`Authorization: Bearer sk-live_...`の形でfetchに直接入れることがある。ユーザーがそのHTMLをそのまま確認なしに公開すると、スキャンツールや攻撃者にキーが検出されてすぐに悪用される。
- 相手がログインなしで開ける状態か確認する
- PCとスマホで最低1回ずつ表示を確認する
- 内部情報・個人情報・不要な外部送信が残っていないか見る
- レビュー期限と修正時の差し替え方を決めておく
ソースで見る場所
`sk-live_` または `sk-test_` をHTMLで全文検索する。`sk-live_` がヒットした場合は本番シークレットキーであり、絶対に共有してはならない。即座にStripeダッシュボードでそのキーをロールオーバー(再生成)する必要がある。`sk-test_` はテスト環境のシークレットキーであり、本番への直接影響はないが、原則としてHTMLに含めるべきではない。
`pk-live_` または `pk-test_` の確認も行う。`pk_`形式はStripe.js初期化に使う公開可能キーで、HTMLに含めることは想定されているが、テスト用(`pk-test_`)と本番用(`pk-live_`)が混在していないか確認する。テスト環境向けのHTMLに`pk-live_`が入っていると、テスト操作が本番Stripeアカウントに影響する事態になりかねない。
- HTML内の外部script・form action・iframeを確認する
- APIキーやトークンらしき文字列がないか検索する
- 画像・CSS・JSのパスが公開後も解決できるか見る
- noindexと認証を混同せず、必要なら両方設定する
安全に共有する設定
`sk_`キーがHTMLに含まれていないことを確認したうえで、`pk_`キーがテスト・本番どちらを使うべきかを用途に合わせて判断する。社外レビューのためのデモHTMLであれば、テスト用公開可能キー(`pk-test_`)を使い、Stripeダッシュボードの「テストモード」でダミーの決済フローを確認できる状態にする。本番キーは本番環境のみで使用するという原則を徹底する。
HTMLをレビュアーに渡す前に、`pk_`キーを `YOUR_STRIPE_PUBLISHABLE_KEY` に置換した版を作成し、そちらを共有する方法も有効だ。決済の動作確認が必要な場合はStripeのテストカード番号(`4242 4242 4242 4242`等)が使えるデモ環境のURLを別途共有する方法の方が、HTMLファイルにキーを含めるより安全だ。
- HTML内の外部script・form action・iframeを確認する
- APIキーやトークンらしき文字列がないか検索する
- 画像・CSS・JSのパスが公開後も解決できるか見る
- noindexと認証を混同せず、必要なら両方設定する
再発防止ルール
AIへのプロンプトに「Stripeのシークレットキー(sk_で始まるもの)はコードに含めないこと。公開可能キー(pk_で始まるもの)は`YOUR_STRIPE_PUBLISHABLE_KEY`のプレースホルダで記述すること。決済処理のサーバーサイドコードはHTMLに含めないこと。」と明示する。この制約でAIは`sk_`キーを生成しなくなり、サーバーサイドロジックがHTMLに混入するのも防げる。
Stripeのシークレットキーは環境変数またはシークレットマネージャーでのみ管理し、コードベースには含めないルールをチームポリシーとして明文化する。GitHubを使っているならGit Secret Scanningを有効化し、`sk-live_`のパターンをプッシュ前に検出する設定を入れる。StripeダッシュボードのWebhookイベントも定期的に確認し、不審な課金試行がないか監視する。
- HTML内の外部script・form action・iframeを確認する
- APIキーやトークンらしき文字列がないか検索する
- 画像・CSS・JSのパスが公開後も解決できるか見る
- noindexと認証を混同せず、必要なら両方設定する
よくある質問
sk-live_キーがHTMLに入った状態で誰かに見られた場合、すぐに被害が出ますか?
HTMLのソースを確認しキーを取得できた時点で、すぐにStripe APIを使った課金や顧客データ取得が可能になる。発覚したら即座にStripeダッシュボードでキーをロールオーバー(無効化して新キーを発行)し、APIログで不審なリクエストがなかったか確認する。
テスト用シークレットキー(sk-test_)がHTMLに含まれていても問題ありませんか?
テストキーで本番への課金は発生しないが、Stripeのテストデータ(顧客・決済履歴等)への不正アクセスや、Webhookエンドポイントの調査に悪用されることがある。原則としてsk_から始まるキーはすべてHTMLに含めない運用を推奨する。
Stripe.jsを初期化するpk_キーはHTMLに書いても本当に安全ですか?
公開可能キー(pk_)はフロントエンドに公開することをStripeが公式に認めており、それ自体での課金はできない設計だ。ただし公開可能キーが漏えいしても課金はできないが、フォームのUIを偽装したフィッシングに悪用されることがあるため、テスト中は`pk-test_`を使い、本番用`pk-live_`は本番環境のみに限定する。