メインコンテンツへスキップ
Security Checker の指摘を修正するのを忘れないでくださいアプリをオンラインで公開する前に、Lovable に組み込まれている Security Checker の指摘事項には必ず対応してください。Security Checker はアプリケーションを自動的にスキャンし、セキュリティを向上させるための有益な推奨事項を提供します。
Lovable AI や Security Checker などのツールは、幅広いセキュリティ問題を検出して防止できますが、アプリがインターネット上で公開された後に発生しうるすべての問題を自動的に発見・対処することは、必ずしも可能でも現実的でもありません。このガイドでは、Lovable アプリが内部でどのように動作しているのか、ビルダーが顧客のデータを保護するために実践すべき重要なセキュリティ対策、そしてよくあるミスを避ける方法について、より深く解説します。

Lovable のアーキテクチャを理解する

特別な指定がない限り、Lovable は次のアーキテクチャでアプリケーションを生成します。
  • フロントエンド: TypeScript/React アプリケーション
  • バックエンド: Supabase Edge Functions(サーバーレス関数)
  • データベース: Supabase(リアルタイム機能を備えた PostgreSQL)
この責務の分離は、セキュリティを維持するうえでの基本原則です。各レイヤーには、それぞれ固有の役割とセキュリティ上の考慮事項があります。

フロントエンドセキュリティ:クライアント側のコードは決して信頼しない

黄金律: フロントエンドコードは公開されている

すべての React コードはユーザーのブラウザ上で実行されており、本質的に公開されています。ユーザーはあらゆるフロントエンドコードを検査・変更したり、迂回したりできます。したがって:
  • フロントエンドコードにシークレットを絶対に保存しない - APIキー、パスワード、機密性の高い設定など
  • フロントエンドコードで検証処理を行わない - クライアントサイドの検証は容易に迂回される
  • フロントエンドから送られてくるデータを信用しない - 必ずエッジ関数側で検証する

よくあるフロントエンドのセキュリティ上のミス

// ❌ 誤り - 絶対に避けてください
const API_KEY = "sk-1234567890abcdef"; // ユーザーに公開される
const validateUser = (userData) => {
  // クライアント側の検証は回避可能
  return userData.email.includes('@');
};
正しい方法は、Lovable にシークレットキーの追加を依頼することです。そうするとフォームが開き、シークレットキーは Lovable のバックエンドに安全に保存されます。

フロントエンドセキュリティの検証と強化に使えるプロンプト例

Stripe決済用のAPIキーをフロントエンドコードに公開せずに安全に追加する
セキュリティ向上のため、バリデーションロジックをReactコンポーネントからエッジ関数に移動する
フロントエンドコードに露出しているシークレット、APIキー、機密情報がないか確認してください。ユーザー設定を表示する設定ページがあるのですが、機密データが表示されていないことを確認したいです
クライアントサイドの検証のうち、バックエンドのエッジ関数に移行すべきものを特定する
さらに多くのプロンプトについては、Lovable の Prompt Library を参照してください。

バックエンドのセキュリティ:ビジネスロジックを Edge Functions に移す

Edge Functions を API レイヤーとして扱う

Supabase Edge Functions には、すべてのビジネスロジック、検証処理、およびセンシティブな処理を集約しましょう。
  • 認証と認可
  • データの検証とサニタイズ
  • ビジネスロジックとワークフロー
  • 外部サービスとの連携
  • センシティブなデータの処理

Edge Functions のベストプラクティス

Edge Functions は、アプリケーションのセキュリティ担当者兼ビジネスマネージャーだと考えてください。アプリの公開部分とは切り離された場所で、安全に実行する必要がある重要な処理を担います。

Edge Functions が担当すべきこと

ユーザー認証と認可
  • ユーザーにアクションを許可する前に、必ず本人であることを検証する
  • 特定の操作に対して、ユーザーが適切な権限を持っているかを確認する
  • 「ログインしている」というユーザーの自己申告だけを信用しない
データの検証とサニタイズ
  • すべての受け取ったデータが正しい形式になっているか確認する
  • ユーザー入力から潜在的に有害な内容を取り除く
  • データを処理する前に、ビジネスルールを満たしていることを確認する
ビジネスロジックとワークフロー
  • 注文処理、支払い計算、ユーザー登録などの複雑なビジネスプロセスを処理する
  • 複数のデータ同士の関係を管理する
  • 1 つの操作の中で複数のステップを調整する
外部サービスとの連携
  • 決済サービス、メールサービスプロバイダー、各種 API などのサードパーティサービスに安全に接続する
  • 機密性の高い APIキーや認証情報を安全に保護する
  • エラーやタイムアウトを適切に処理する
機密データの処理
  • 個人情報、金融データ、その他の機密性の高い情報を処理する
  • 必要に応じて暗号化などのセキュリティ対策を適用する
  • セキュリティ監査のために重要なイベントを記録する

Edge Functions のセキュリティ上の利点

分離: Edge Functions はフロントエンドとは分離された安全な環境で実行されるため、攻撃者が機密コードやデータにアクセスすることがはるかに困難になります。 セキュリティの一元化: すべてのセキュリティチェックが 1 か所で行われるため、セキュリティポリシーの維持や更新が容易になります。 クライアント側への露出なし: 機密性の高いビジネスロジックはユーザーのブラウザに届かないため、閲覧・改ざんされることがありません。 一貫した検証: すべてのリクエストが同じ検証プロセスを通過するため、アプリケーション全体で一貫したセキュリティを確保できます。

安全な Edge Functions 向けのプロンプト例

適切な検証とセキュリティチェックを備えたユーザー登録用のエッジ関数を作成してください。ユーザーはサインアップ時にメールアドレス、パスワード、およびオプションでプロフィール画像を提供する必要があります
決済処理ロジックをフロントエンドから安全なエッジ関数に移行します。現在、ブラウザで直接Stripe決済を処理しているチェックアウトコンポーネントがあります
ファイルアップロード用のエッジ関数を構築し、ファイルタイプとサイズの検証を実装します。ユーザーはプロフィール画像(最大5MB)とドキュメント(PDFのみ、最大10MB)をアップロードできます
ユーザーがサインアップした際に、ウェルカムメールを安全に送信するためのエッジ関数を設定します。プロバイダーAPIを使用して、ユーザー名とアカウント詳細を含むパーソナライズされたウェルカムメールを送信します
外部サービスからのWebhookイベントを処理するエッジ関数を実装します。Stripeの決済確認を処理し、データベース内の注文ステータスを更新します
より多くのプロンプトについては、Lovable の Prompt Library を参照してください。

データベースセキュリティ: RLS はシンプルに保ち、早期から導入しよう

Lovable における Row Level Security(RLS)

Lovable はテーブルに対して自動的に基本的な RLS ポリシーを設定しますが、アプリのセキュリティ要件に合わせて必ず確認し、カスタマイズしてください。RLS は、データベース内のどのデータを誰が閲覧・変更できるかを決めるルールだと考えてください。 早期の見直しが重要です: ユーザーがすでにデータを作成した後よりも、アプリが新しいうちに RLS ポリシーを調整する方がはるかに簡単です。 シンプルな方が安全です: RLS ポリシーは、複雑なビジネスロジックではなくデータアクセスに集中させ、シンプルに保ちましょう。Lovable のデフォルトポリシーは、たいていは良い出発点になります。

Lovable アプリでよくある RLS パターン

個人データの保護
  • ユーザーは自分のプロフィール、設定、個人データにのみアクセスできる
  • デフォルトのパターン: 「Users can only access their own data」
チームベースのアクセス
  • チームメンバーは、自分が所属するチーム内で共有されているプロジェクトデータにアクセスできる
  • パターン: 「Users can access data from teams they belong to」
所有者付きの公開コンテンツ
  • だれでも閲覧できる公開投稿だが、編集できるのは所有者のみ
  • パターン: 「Anyone can read, only owners can modify」
組織ベースのアクセス
  • 会社の従業員は自社のデータにアクセスできる
  • パターン: 「Users can access data from their organization」

Lovable アプリでの RLS の見直し

テーブルを確認する
  • どのテーブルで RLS が有効になっているか確認する
  • 機密データのテーブルが適切に保護されていることを確認する
  • 公開データのテーブルに適切な読み取りポリシーが設定されていることを確認する
アクセスパターンをテストする
  • ユーザーが自分のデータだけを見られることを確認する
  • 共有データに適切なユーザーだけがアクセスできることをテストする
  • 公開データが全ユーザーに表示されることを確認する
よくある問題点
  • 機密データに対して RLS が有効化されていないテーブル
  • 不要に多くのデータを公開してしまう、許可範囲が広すぎるポリシー
  • 新しいテーブルや機能に対してポリシーが未設定であること

RLS レビューのためのプロンプト例

LovableアプリのRLSポリシーを見直し、ユーザーが自分のデータのみにアクセスでき、共有データが適切に保護されていることを確認してください
ユーザーテーブルと投稿テーブルのRLSポリシーを確認してください - ユーザーは自分のプロフィールのみを表示できますが、すべての公開投稿を閲覧できます
settingsテーブルにRLSポリシーを追加し、ユーザーが自分の設定のみにアクセスできるようにする
過度に緩いアクセス権限を修正 - 現在ユーザーは全ユーザーの投稿を閲覧できるため、自分の投稿と公開投稿のみに制限してください
チームとプロジェクトテーブルにRLSを設定して、チームメンバーが自分のチームのプロジェクトのみを表示できるようにする
マルチテナントアプリでユーザーが自組織のデータのみにアクセスできるようにする
ユーザーが不正にデータへアクセスできてしまうセキュリティホールがないか、RLSポリシーを監査する
複雑なRLSポリシーをセキュリティを維持しながら簡素化する - 現在のポリシーは複雑すぎます

RLS クイックチェックリスト

  • すべての機密テーブルで RLS が有効になっている
  • ユーザーは自分の個人データにしかアクセスできない
  • 共有データには適切なアクセス制御が設定されている
  • 新しいテーブルには自動的に RLS ポリシーが適用される
  • ポリシーがシンプルでわかりやすい

認証セキュリティ:ロジックはサーバー側で行う

認証ロジックは必ずサーバーで実行する

すべての認証に関する判定処理、トークンの検証、ユーザーの検証は、ブラウザではなくサーバー側で行う必要があります。クライアント側の認証は簡単にバイパスされたり改ざんされたりしてしまいます。 重要な原則:
  • クライアント側の認証チェックを決して信用しない - ユーザーはブラウザのコードを変更できます
  • トークンはサーバーで検証する - 認証は必ずエッジ関数内で検証してください
  • セッション管理はサーバー側で行う - Supabase に安全なセッション保存を任せてください
  • 認証用のシークレットを決して公開しない - APIキーやトークンをフロントエンドに渡してはいけません

セキュアな認証フロー

// ❌ 誤り - クライアント側の認証ロジック
const isAuthenticated = localStorage.getItem('authToken') !== null;
if (isAuthenticated) {
  // ユーザーによって回避可能
  showAdminPanel();
}

// ✅ 正しい - サーバー側の認証検証
// エッジ関数内:
const { user } = await supabase.auth.getUser();
if (!user) {
  return new Response('Unauthorized', { status: 401 });
}
// 認証済みロジックを実行

認証に関するベストプラクティス

サーバーサイドでの検証:
  • リクエストを処理する前に、エッジ関数内で必ずユーザー認証を確認する
  • React コンポーネントではなく、サーバー側でユーザーの権限やロールを確認する
  • セッショントークンをデータベースまたは認証サービスに対して検証する
クライアントサイドでの処理:
  • 安全なトークンの保存には Supabase の組み込みセッション管理を使用する
  • 認証状態に基づいて UI を出し分けるが、セキュリティ上の判断は決して行わない
  • セッションが期限切れになったらログイン画面にリダイレクトするが、その前に必ずサーバー側で検証する

ワークスペース保護:社内アプリケーションのセキュリティ確保

社内アプリの「visibility」を「Workspace」に設定する

インターネットからアクセスできないようにしたいアプリケーションでは、次を実施します:
  • プロジェクトダッシュボードで社内アプリの “Project visibility” を “Workspace” に設定する
  • インターネット上に公開されていないことを確認する
  • すべての社内ツールで適切な認証を利用する
  • 非公開アプリケーションへのアクセスを定期的に監査する

セキュリティのベストプラクティス概要

開発ワークフロー

  1. 最初からセキュリティを意識する - 当初から RLS と認証を実装する
  2. セキュリティチェッカーを使う - 定期的に Lovable のセキュリティチェッカーを実行する
  3. 推奨事項に従う - すべてのセキュリティに関する提案を適用する
  4. 十分にテストする - セキュリティ対策が想定どおりに機能していることを確認する
  5. セキュリティに関する判断を文書化する - セキュリティに関する選択とその理由を記録しておく

定期的なセキュリティ監査

  • エッジ関数の権限を確認する
  • RLSポリシーを見直す
  • シークレットが漏えい・露出していないか確認する
  • 認証フローを検証する
  • アクセス制御をテストする

一般的なセキュリティチェックリスト

  • フロントエンドコードにシークレットを含めていない
  • すべてのバリデーションをエッジ関数で実行している
  • RLS ポリシーが実装され、テストされている
  • セキュアな方法で認証を行っている
  • 社内向けアプリが適切に保護されている
  • セキュリティチェッカーを実行し、推奨事項に従っている
  • 定期的にセキュリティレビューを実施している

Lovable セキュリティチェッカーの使い方

Lovable には、潜在的なセキュリティ問題を特定するのに役立つ組み込みの セキュリティチェッカー が用意されています。
  1. プロジェクトのダッシュボードで セキュリティチェッカーを実行する
  2. すべての推奨事項を注意深く確認する
  3. 提案された修正を速やかに実施する
  4. 変更後に 再度チェッカーを実行する
  5. 例外がある場合は 明確な理由とともに記録する
セキュリティは一度きりの作業ではなく、継続的なプロセスです。アプリケーションの変化に合わせて、定期的にセキュリティ対策を見直し、更新してください。