非機能要件を自分の作成したプロジェクトに当てはめてみた
システム開発では、画面や機能だけでなく、「安全に使えるか」「障害時に復旧できるか」「快適に動作するか」といった非機能要件も重要です。
今回は、自分が作成したNext.js、Vercel、Supabaseを使用したWebアプリケーションに、非機能要件の一つである「セキュリティ」を当てはめて考えてみました。
今回のシステム構成
今回のプロジェクトでは、次の技術を使用しています。
- フロントエンド:Next.js
- ホスティング・デプロイ:Vercel
- 認証・データベース:Supabase
システムの流れは、次のようになります。
利用者
↓
Next.js
画面表示・入力処理・認証確認
↓
Vercel
Webサイトの公開・実行
↓
Supabase
ログイン認証・データベース・権限管理
この構成に対して、セキュリティ要件をそれぞれのサービスに当てはめてみます。
1. 法令・契約条件
個人情報を扱う場合は、個人情報保護法などの法令を意識する必要があります。
例えば、次のような対応を行います。
- 必要以上の個人情報を保存しない
- パスワードを平文で保存しない
- 利用目的を明確にする
- 不要になったデータを削除する
- 外部サービスの利用規約を確認する
Supabaseを利用する場合は、保存されるデータの種類や、サービスの利用条件も確認します。
2. セキュリティリスク分析
開発したシステムに、どのようなリスクがあるかを考えます。
例えば、次のようなリスクがあります。
- 他人のユーザー情報を閲覧される
- 管理者画面に一般ユーザーがアクセスする
- APIキーが外部に漏れる
- 不正なファイルをアップロードされる
- 大量アクセスによってサービスが利用できなくなる
このように、実際に攻撃される可能性を想定して、必要な対策を考えます。
3. セキュリティ診断
Next.jsやSupabaseで使用しているライブラリには、脆弱性が発見されることがあります。
そのため、次のような確認が必要です。
- npmパッケージを定期的に更新する
- 不要なパッケージを削除する
- 脆弱性診断ツールを使用する
- Supabaseの認証やデータベース設定を確認する
- Vercelの公開設定を確認する
一度設定したら終わりではなく、定期的に見直すことが重要です。
4. セキュリティリスクの管理
リスクを発見した場合は、そのままにせず対策を行います。
例えば、Next.jsやライブラリに問題が見つかった場合は、バージョンを更新します。
また、Supabaseのデータベースについても、ユーザーが必要以上のデータを取得できないように権限を見直します。
Vercelでは、誰が本番環境へデプロイできるのかを制限します。
5. アクセス・利用制限
ユーザーによって、利用できる機能を分けます。
例えば、管理者と一般ユーザーで画面を分ける場合は、次のような流れになります。
ログイン
↓
ユーザーの権限を確認
├─ admin → 管理者画面
└─ user → 一般ユーザー画面
ただし、画面上でボタンを隠すだけでは安全ではありません。
Next.jsのサーバー側でも権限を確認し、さらにSupabaseのRLSでもデータへのアクセスを制限します。
6. データの保護
個人情報やパスワードなどの重要なデータは、安全に管理する必要があります。
Supabase Authを利用すれば、パスワード認証などを自分で一から実装せずに済みます。
また、次のような情報は、ソースコードに直接書かないようにします。
- データベースのパスワード
- Supabaseの秘密鍵
- 外部APIのキー
- 管理者用の認証情報
これらは環境変数で管理します。
NEXT_PUBLIC_SUPABASE_URL=...
SUPABASE_SERVICE_ROLE_KEY=...
SUPABASE_SERVICE_ROLE_KEYのような秘密鍵は、ブラウザ側に公開してはいけません。
7. 不正監視・ログ
不正アクセスが発生した場合に調査できるよう、ログを取得します。
例えば、次のような情報を記録します。
- ログインの成功・失敗
- 権限エラー
- 不正なAPIアクセス
- データの更新履歴
- ファイルのアップロード履歴
Vercelではアプリケーションの実行ログ、Supabaseでは認証やデータベースに関するログを確認できます。
8. ネットワーク対策
通信を暗号化するため、HTTPSを使用します。
Vercelで公開したWebサイトは、基本的にHTTPSで通信できます。
また、次のような対策も考えられます。
- 不正な通信を制限する
- APIの利用回数を制限する
- CORSを適切に設定する
- 大量アクセスへの対策を行う
- 不要なポートや機能を公開しない
9. マルウェア対策
ユーザーが画像やファイルをアップロードできるシステムでは、不正なファイルを登録される可能性があります。
そのため、次のような対策を行います。
- ファイルの種類を制限する
- ファイルサイズを制限する
- ファイル名をそのまま使用しない
- 実行可能なファイルを拒否する
- 必要に応じてウイルスチェックを行う
Supabase Storageを使用する場合も、誰がファイルをアップロード・閲覧できるのかを設定します。
10. Web対策
Webアプリケーションでは、入力値をそのまま信用してはいけません。
例えば、次のような攻撃に注意します。
- XSS
- SQLインジェクション
- CSRF
- 不正なリクエスト
- セッションの乗っ取り
Next.js側で入力値をチェックし、Supabase側でも適切な権限設定を行います。
11. セキュリティインシデント対応と復旧
万が一、APIキーの漏えいや不正アクセスが発生した場合に備えて、対応方法を決めておきます。
例えば、次のような手順です。
異常を発見
↓
アクセスログを確認
↓
漏えいしたキーを無効化
↓
新しいキーを発行
↓
不正なデータやユーザーを確認
↓
必要に応じて復旧・再デプロイ
Vercelでは問題のあるデプロイを確認し、以前のバージョンへ戻すこともできます。
Supabaseでは、データベースのバックアップや復旧方法を確認しておく必要があります。
まとめ
今回のプロジェクトにセキュリティ要件を当てはめると、次のように整理できます。
- Next.js:認証確認、入力チェック、APIの権限確認
- Vercel:HTTPS、環境変数、デプロイ管理、ログ確認
- Supabase:ユーザー認証、データベース、RLS、Storage管理
特に重要なのは、Next.js側だけで認証や権限を制御しないことです。
Next.jsで認証・認可
+
SupabaseのRLSでデータ保護
+
Vercelで公開環境と秘密情報を管理
このように、複数の場所でセキュリティ対策を行うことで、より安全なWebアプリケーションにできます。