「動くコード」が「安全なコード」とは限らない現実
前回は、バイブコーディングに潜むセキュリティリスクの具体例を解説しました。生成AIは、ソフトウェア開発の生産性を劇的に向上させましたが、その速度と引き換えに、私たちは従来からあるセキュリティリスクを見過ごしがちになっています。
AIの学習データはインターネット上の膨大なコードに依存しており、その中には古く脆弱なサンプルコードも数多く含まれています。これは、OWASP Top 10 for LLM Applicationsで指摘されている「LLM09:偽情報」のリスクの一側面でもあります。
AIによって生成されたコードは、情報の正確性を検証するわけではなく、統計的にもっともらしいシーケンスを生成します。そのため、一見すると正しく動作するものの、セキュリティ上の欠陥を抱えたコードを意図せず生成してしまうのです。
本記事では、AIが生成したコードに直接現れやすい、古典的かつ具体的な脆弱性を、Webアプリケーションの重大なセキュリティ脅威をランク付けした「OWASP Top 10」から抜粋して解説します。
開発者がAIの提案をそのまま受け入れ、「動くコード」を「安全なコード」と勘違いしてしまう典型的なパターンに焦点を当て、その危険性と対策を明らかにします。
AIには理解できない「データの所有権」
A01:2021-アクセス制御の不備
アクセス制御の不備は、アプリケーションのロジックにおいて、認証されたユーザーが権限外の機能やデータにアクセスできてしまう脆弱性を指します。「誰が(主体)」「どの情報に(リソース)」「何をしてよいか(権限)」という認可ロジックの欠陥が原因で発生します。
AIは、アプリケーション全体のビジネスロジック、役割(Role)、そしてデータの所有権といった、人間が意図しているコンテキストを完全には理解していません。
そのため「ユーザー情報を表示するAPIを作成して」と依頼すると、データの所有権についてはプロンプトでは触れられていないため、本来は閲覧できないユーザーにも情報を渡してしまうコードを生成する可能性があります。
具体的な例としては、ログイン必須や管理者アカウント限定のページに対して適切なアクセス制御が正しく設置されておらず、誰でもアクセスができてしまうといったケースが考えられます。
具体例:BaaSにおける認可ルールの不備
連載の第一回でも軽く触れましたが、BaaS(Backend as a Service)のセキュリティルール設定は、この脆弱性が現れやすい典型的な例です。
開発初期段階のサンプルとして、「誰でも読み書き可能」あるいは「認証ユーザーなら誰でもOK」といった、データの所有者を無視した安易なルールのまま開発が進んでしまうことがあります。
脆弱な設定例(Firebase/Supabase)
-
誰でも読み書き可能:allow read, write: if true;
- ルールが緩すぎます。さらにディレクトリリスティングも有効になっているためファイルの一覧にアクセスできてしまいます。
-
認証ユーザーなら誰でもアクセス可能:allow read, write: if request.auth != null;
- このルールでは、ユーザーAがユーザーBのデータを自由に読み書きできてしまいます。
安全な実装例(Supabase RLS)
行レベルセキュリティ(RLS)を用いて、「自分のデータにしかアクセスできない」というポリシーをアプリケーションロジックの一部としてデータベースレベルで強制することが不可欠です。
-- profilesテーブルでRLSを有効化 ALTER TABLE profiles ENABLE ROW LEVEL SECURITY; -- 認証ユーザーが自身のプロフィールのみを閲覧・更新できるポリシーを作成 CREATE POLICY "Users can view their own profile." ON profiles FOR SELECT USING (auth.uid() = user_id); CREATE POLICY "Users can update their own profile." ON profiles FOR UPDATE USING (auth.uid() = user_id);
このように、データベースとAPIエンドポイントレベルで、リクエストされたリソースの所有者が、操作を実行しているユーザーと一致することを常に検証する必要があります。
