【総集編】公開前に自分でやる5つのチェック — 全部ブラウザだけ、合計30分

AIで作ったアプリを公開する前に、自分でできるチェック5つを1ページと1本の動画(約12分)にまとめました。URLの数字・F12でキー・/admin・金額の書き換え・画像URL。共通する一文は「決めるのはサーバー側。画面とURLは信じない」。

動画で見る

結論から

AIで作ったアプリを公開する前に、エンジニアに頼まなくても自分でできるチェックは5つあります。どれもブラウザだけで、1つ5分。合計30分で、実際に起きた事故(Moltbook、Lovable 製アプリの CVE、RedAccess の5,000本)の入口の大半を、自分で先に見つけられます。

この記事は、これまでの5本の総集編です。5つの手順を1ページにまとめ、動画も1本(約12分)にしました。

  1. URLの数字を1つ変える → 他人のデータが見えたら、サーバーが本人確認をしていない
  2. F12で「sk-」「service_role」を検索 → 出てきたら、キーが全員に見えている
  3. シークレットウィンドウで /admin を開く → 開けたら、管理画面が全員に公開されている
  4. URLの金額・数量を書き換える → 通ったら、サーバーが画面の値を信じている
  5. ログアウトして画像URLを直接開く → 表示されたら、ファイルが全員に公開されている

5つに共通する一文は、「決めるのはサーバー側。画面とURLは信じない」です。

公開前に自分でやる5つのチェック

準備するもの(5分)

  • Chrome の シークレットウィンドウ(Mac: ⌘⇧N / Windows: Ctrl+Shift+N)。「ログインしていない誰か」になれます
  • テスト用アカウント2つ(Aさん・Bさん。ダミーのメールで)
  • 公開URL(ローカルではなく、実際に使うURL)
  • 結果をメモする場所。各項目を ◯(合格)/✗(未対策)/?(分からない) で

チェック①:URLの数字を1つ変える(5分)

手順:Aさんでログイン → 自分の予約・注文・プロフィールのページを開く → URLの /reservations/12 ?id=12 の数字を 13 に変えて Enter。

  • 他人のデータが表示された → ✗
  • 「表示できません」「見つかりません」 → ◯

なぜ:サーバーが「13番はログイン中の本人のものか」を確かめず、頼まれた番号をそのまま返しています。リンクを出していなくても、URLは誰でも打てます。

AIへの一文:「IDで取得するすべての処理で、そのデータがログイン中のユーザーのものかをサーバー側で確認して。他人なら403。」(→ 詳しくは「URLの数字を1つ変えてみる」)

チェック②:F12でキーを検索する(3分)

手順:公開URLを開く → F12 → Sources タブ → ⌘⇧F(Ctrl+Shift+F)で全文検索 → 「sk-」「service_role」「eyJ」。

  • 出てきた → ✗。そのキーは、アプリを開いた全員のブラウザに配られています
  • 0件 → ◯

なぜ:AIは動作確認が早いので、まずフロントにキーを書きます。フロントに書いたものは「表示していない」だけで「隠せている」ではありません。

AIへの一文:「フロントに含まれるAPIキーをすべて列挙して、サーバー側の環境変数に移し、フロントからはサーバー経由で呼ぶように書き換えて。」そして古いキーは無効化して再発行。(→「AIはAPIキーをまずフロントに書く」/漏れたあとは「キーが漏れた瞬間の30分」)

チェック③:シークレットウィンドウで /admin を開く(3分)

手順:シークレットウィンドウで アプリのURL/admin を開く。ついでに /dashboard /manage /users も。

  • 管理画面が表示された → ✗
  • ログイン画面に飛ばされた → ◯。さらにAさん(一般ユーザー)でログインして開き、403なら ◯

なぜ:「リンクを置いていない」は守っていません。サーバーが「ログインしているか」「管理者か」を確かめていないだけです。

AIへの一文:「管理画面と管理用APIすべてに、サーバー側でログイン済みか・管理者かを確認する処理を入れて。未ログインはログイン画面へ、管理者以外は403。」(→「シークレットウィンドウで /admin を開く」)

チェック④:URLの金額・数量を書き換える(5分)

手順:お会計・注文確認のページで、URLやフォームに price=12800 qty=1 のような値が無いか見る → price=1 に書き換えて開く。フォームなら F12 → Elements で hidden の値を書き換えて送信。

  • 「¥1」で確定できた → ✗
  • 定価のまま、または拒否された → ◯

なぜ:画面側のチェックは、送る側が書き換えられます。「入力チェックを入れて」と頼むと、AIは画面側に書きます。決めるのはサーバー側。

AIへの一文:「金額は画面の値を使わず、サーバー側で定価から再計算して。数量・権限・入力もサーバー側で検証して、画面側だけで済ませないで。」(→「サーバー側で検証して」の一言)

チェック⑤:ログアウトして画像URLを直接開く(3分)

手順:ログイン中に、アップロードした画像・PDF を右クリック →「アドレスをコピー」→ シークレットウィンドウで開く。

  • 表示された → ✗。ページの鍵と、ファイルの鍵は別です
  • 「ログインが必要」「403」「Not found」 → ◯

なぜ:画像やPDFは、ページとは別の置き場(ストレージ)から直接配られます。AIは「画像を表示して」に対して、いちばん簡単な「公開バケット」を選びます。

AIへの一文:「個人に紐づくファイルを非公開バケットに移して、パスは user_id で始め、本人だけが読めるポリシーに。表示はサーバー側で本人確認してから期限付きの署名付きURLで。」(→「ログアウトして画像URLを直接開く」)

結果の読み方

  • ✗が1つでもあれば、公開前に直す。どれも「他人のデータが見える」「キーが漏れる」に直結します
  • ◯が5つでも、終わりではない。これは「自分で見つけられる10項目」の半分。コードを読まないと分からない残り(管理APIの権限、Git履歴のキー、サーバー側の検証、バックアップ、依存パッケージ…)は、エンジニアに頼みます
  • 頼むときは、この5つの◯✗メモと、「頼む前に用意する5つ」(公開URL・コード・テスト用アカウント・一文とデータ・外部サービス)を添えてください。返事が「いつ空いていますか」から「ここが危ない、概算は〜」に変わります

Supabase を使っているなら、もう1つ

Table Editor で赤い「RLS disabled」が無いか。緑でもポリシーが USING (true) なら全員に公開です。AIは動かすために RLS を切り、動いた瞬間に戻す理由が消えます。(→「AIはRLSを切って開発し、戻さない」/「Moltbook」)

よくある質問

5つ全部やる時間がありません。どれからですか。

①と③です。この2つで、実際の事故の入口(他人のデータ・管理画面)の多くが分かります。次に②(キー)。④⑤は、決済とアップロード機能がある場合に。

◯だったのに、あとで漏れました。

機能を追加するたびに、AIは同じ順番で作業します。5つのチェックは公開前に1回ではなく、機能を足すたびにやり直してください。30分です。

エンジニアに全部任せたほうが早くないですか。

この5つは、エンジニアが最初の30分にやることと同じです。先にやっておくと、その30分がコードの中を見る時間に使われます。費用も返事の速さも変わります。