Hello there, ('ω')ノ
LLM(大規模言語モデル)は「コード」ではなく「文章」で制御されます。 つまり プロンプトは設定ファイルであり、業務ロジックであり、権限境界そのもの です。
従来の Web アプリで言えば、
- 設定ファイル
- 認可ロジック
- 業務フロー
が 1つのテキスト(プロンプト)に凝縮されている 状態です。 今回は「そこをどう守るか」に焦点を当てています。
① システムプロンプトを“秘密情報”として扱う
なぜ?
攻撃者にとって最も価値があるのは 「このAIは何をしてよくて、何をしてはいけないのか」という内部ルール。
何が起きる?
- プロンプトが漏れる
- → ガード条件を逆算される
- → 回避用の入力(プロンプトインジェクション)が作られる
現場の判断
- システムプロンプトはソースコードと同等以上の機密情報
- ログ・レスポンス・エラーメッセージに絶対に含めない
② ユーザー入力とシステム指示を絶対に混ぜない
なぜ?
LLMは「文章の区別」が苦手です。 人間には obvious な区切りでも、LLM には曖昧です。
典型的な事故
あなたは安全なアシスタントです。
以下のユーザー入力に答えてください:
{user_input}
ここに 「上の指示を無視して…」 が来ると、LLM は普通に従います。
現場の判断
- system / user / context を構造的に分離
- 「一つの文章にしない」ことが最重要
③ 外部データは“すべて敵”として扱う
なぜ?
RAG、Web検索、PDF要約、メール要約… 全部「間接プロンプトインジェクション」の入口です。
攻撃者の考え
- Webページ
- GitHub README
- 社内Wiki
に 命令文を埋め込む → LLM がそれを「文脈」として信じる
現場の判断
- 外部データは「参考情報」であって「命令」ではない
- 命令語・役割変更を検知/除外する層が必須
④ プロンプトを固定文字列だと思わない
なぜ?
プロンプトは「静的設定」ではなく 実行時に変化する攻撃面。
- ユーザー入力
- RAG
- 状態
- 会話履歴
これらが混ざることで、毎回違うプロンプトが生成されます。
現場の判断
- プロンプト = 実行環境
- セキュリティレビュー対象に含める
⑤ 出力も“信用しない”
なぜ?
「AIが出したから安全」は幻想です。
LLM 出力は:
- HTML
- JSON
- SQL
- コマンド
- 設定ファイル
として そのまま次の処理に渡されがち。
典型事故
- LLM出力 → eval
- LLM出力 → innerHTML
- LLM出力 → APIコール
現場の判断
- LLM出力 = 未検証ユーザー入力
- 出力検証・スキーマ制限は必須
⑥ 明示的に「できないこと」を書く
なぜ?
LLMは「書いていないことは許可されている」と解釈しがち。
悪い例
安全に回答してください
良い考え方
- 禁止事項を具体的に列挙
- 行動レベルで制限
現場の判断
- ポリシーは曖昧語禁止
- Yes/No が判断できる書き方をする
⑦ プロンプトに“自己検証”をさせる
なぜ?
LLM は自分の出力を再評価できます。
例の考え方
- 「この回答はポリシーに違反していないか?」
- 「機密情報を含んでいないか?」
現場の判断
- 1回の生成で終わらせない
- 生成 → 検証 → 修正の流れを作る
⑧ 会話履歴を無制限に信用しない
なぜ?
会話履歴は 攻撃者が積み上げる汚染データ。
- 少しずつ条件を緩める
- 「前提」をすり替える
- 誘導する
現場の判断
- 会話履歴は定期的にリセット
- 重要操作前はクリーンな文脈で再評価
⑨ 権限の概念を LLM に持ち込む
なぜ?
LLM は「誰が言ったか」を本質的には理解しない。
危険な設計
- 管理者操作も一般ユーザー操作も同じプロンプト
現場の判断
- 権限ごとにプロンプトを分離
- 「管理者だからできる」は明示的に定義
⑩ “完璧に防げない”前提で設計する
なぜ?
プロンプトインジェクションは 構造的に完全防御が難しい。
現場の正解
- 検知
- ログ
- 影響範囲の限定
- 迅速な修正
現場の判断
- 侵入前提設計(Assume Breach)
- AIも例外ではない
経営・意思決定者向けまとめ
- LLMは「便利な機能」ではなく「新しい実行基盤」
- プロンプトは コード+設定+権限 を兼ねている
- 守らないと「仕様どおりに壊される」
Best regards, (^^ゞ