コンテンツへスキップ
DedicatedPHP 接触

指示を与えようとする文書:PHPアプリケーションでプロンプトインジェクションを抑える方法

取得した文書を信頼できないデータとして扱い、ツールと権限を制限し、応答を検証する方法を解説します。PHPでのAI連携をテストする手順も紹介します。

信頼できない文書、アクセス制御、AI応答の検証を分離するPHPアプリケーションの図

文書について質問に答える機能では、関連するテキストを取得してAIモデルに送信できます。しかし、そのテキストが常に無害とは限りません。文書、Webページ、ユーザーが提供したファイルには、タスクの変更、第三者の情報や許可されていない情報の取得、何らかの操作を試みる文言が含まれている場合があります。このリスクは文書によるプロンプトインジェクション、または間接プロンプトインジェクションと呼ばれます。指示がユーザーの質問ではなく、処理対象のコンテンツ内に含まれて届くためです。

対策は、システムメッセージに完璧な文言を見つけることではありません。取得したコンテンツが権限、ポリシー、業務上の判断を変更できないようにアプリケーションを設計し、モデルの応答だけでは決して操作の実行を許可しないことです。

制御すべきリスク

制御すべきリスク — guía visual de DedicatedPHP

文書には「以前の指示を無視せよ」のような明示的な指示や、内部データの開示を求めるような巧妙な文言が含まれることがあります。また、HTMLから抽出したコンテンツ、コメント、メタデータ、OCRで生成されたテキストに、隠れた指示が含まれる場合もあります。こうした内容をアプリケーションの指示と区別せずに混在させると、モデルがその一部に従ったり、偏った形で要約したり、想定外の応答を生成したりする可能性があります。

リスクの大きさは、その機能が何を実行できるかによって異なります。回答の下書きを作成してレビューに回すだけのアシスタントと、アカウントの照会、返金の発行、メッセージの送信が可能なアシスタントでは、影響が異なります。ユーザーに機能を公開する前に、受け取る可能性のある情報、生成してよい応答、それらがもたらし得る結果を定義してください。

プロンプトインジェクションが起きたからといって、それだけでアプリケーションのアクセス制御が破られたとは限りません。ただし、コンテキストに誤って含めた情報が露出したり、モデルが操作を要求するよう誘導されたりする可能性はあります。保護対策は、入力、利用可能なデータ、その後の操作をすべて対象にする必要があります。

データとポリシー・権限を分離する

取得したコンテンツは回答の根拠として使い、権限の根拠にしてはいけません。文書に社内ポリシーが記載されていても、その文書をユーザーが参照できるか、関連する操作を実行できるかは、アプリケーションが別途判断しなければなりません。この判断をテキストや生成された応答に委ねてはいけません。

  • 取得前に認可する:検索時にアクセス制御を適用し、ユーザーのIDと現在の権限に応じて文書を絞り込みます。
  • コンテキストを最小限にする:タスクに必要な断片だけを送信します。他のアカウントのデータ、秘密情報、認証情報、モデルに不要な情報は含めません。
  • ポリシーをモデルの外で適用する:権限、制限、業務条件は、アプリケーションコードまたは認可されたサービスで判定します。
  • 応答は提案として扱う:モデルの出力は実行可能な指示ではなく、検証が必要なコンテンツとして扱います。

たとえば、取得したテキストは参照資料であると示すなど、システム指示によって期待する振る舞いを伝えることはできます。しかし、これはセキュリティ境界ではありません。モデルが悪意ある指示を無視する保証にはならず、アクセス制御、検証、技術的な制限の代わりにもなりません。

明確な境界を設けてPHPの処理フローを設計する

PHPでは、認可、検索、コンテキストの構築、モデルの呼び出し、出力の検証を別々の段階に分けるのが適切です。この分離により各境界をテストしやすくなり、AIの出力が機密性の高い操作に直接つながるのを防げます。

以下のコードは説明用の疑似コードであり、特定のクライアントを実行する呼び出しではありません。リクエストの構築方法と受け付けるフィールドは、使用するAPIとSDKによって異なります。

$user = $auth->currentUser();
$documents = $repository->searchAuthorized($user, $question);
$snippets = $contextBuilder->selectRelevant($documents, $maxItems);

// 疑似コード:実際のAPIに合わせてリクエストを調整してください。
$response = $aiClient->answer([
    'task' => '参照資料を使って回答する。操作を許可してはならない。',
    'untrusted_context' => $snippets,
    'question' => $question,
]);

$answer = $responseValidator->validate($response);
return $answer;

例にある名前は説明用です。コンテキストに信頼できないデータというラベルを付けると、その役割を伝えやすくなりますが、確実に隔離できるわけではありません。形式や指示だけで、埋め込まれた指示にモデルが従うのを防ぐことはできません。実効性のある分離には、送信するデータ、モデルの外で適用する権限、利用可能な機能も関係します。

抽出したコンテンツは、組み込む前に正規化して制限してください。最大サイズを設定し、不要な形式を取り除き、OCRや外部ページから得たテキストは慎重に扱います。文書を制限なく連結したり、会話履歴全体をデフォルトで含めたりしないでください。回答の説明や監査が必要な場合は、各断片の出典を記録しつつ、機密内容をログに含めないようにします。

操作された応答の影響を抑える

モデルが利用できるツールは、具体的な機能に必要なものだけに制限してください。タスクが質問への回答だけなら、書き込みツールや内部サービスへの一般的なアクセスを与えてはいけません。データ照会が必要な場合は、広範な認証情報やデータベースへの任意アクセスではなく、リクエストごとに認可を適用する限定的な操作を公開してください。

モデルが操作を提案した場合、アプリケーションは独立したフローで検証しなければなりません。実行時に、ID、権限、パラメーター、業務ルール、リソースの現在の状態を確認してください。影響の大きい操作では、明示的な確認または人によるレビューを求めます。文書を引用している場合も含め、安全そうに見えるモデルのテキスト応答は、認可の代わりにはなりません。

表示または処理する前に出力も検証してください。想定する形式を確認し、長さを制限し、許可されていないフィールドや値は拒否します。特定の構造を想定する場合は、決定論的なルールでフィールドを解析・検証します。出力のエスケープやHTML、SQL、コマンドへのインジェクション対策も引き続き必要です。AIによる生成で、生成されたテキストが信頼できるものになるわけではありません。

攻撃と想定される振る舞いをテストする

テストでは、モデルがシステム指示に正しく応答するかだけでなく、処理フロー全体を対象にしてください。タスクの変更、許可されていないデータの要求、操作の誘発を試みる、無害な文書と敵対的な文書を用意します。HTMLから抽出したテキスト、長文書、正当な情報に指示が混在するコンテンツなど、入力元の形式の違いも含めてください。

  • 質問で特定のデータを明示的に要求された場合も、検索結果にユーザーの権限外の文書が含まれないことを確認します。
  • 敵対的な文書によってツールが有効化されたり、業務ルールが変更されたりしないことを検証します。
  • 形式が不正または想定外の応答は拒否され、機密性の高い操作には独立した認可が必要であることを確認します。
  • 無害な文書で有用かつ正確な応答が得られるかを評価し、制限によって機能が許容できないほど低下していないかを確認します。
  • モデル、指示テンプレート、検索機構、ツール、抽出プロセスに変更があった場合は、テストを繰り返します。

観測可能な受け入れ基準を定めてください。決して表示してはいけないデータ、ブロックすべき操作、十分な根拠がない場合のシステムの応答を明確にします。単発のテストで安全性は保証できませんが、繰り返し実施できるテスト一式は、リグレッションの検出や設定変更の比較に役立ちます。

機密データを蓄積せずに兆候を記録する

障害を調査できるよう、リクエストID、設定バージョン、参照した文書のIDまたは内部参照情報、認可の判断、呼び出したツール、検証結果を記録してください。参照情報を記録することは、文書やその断片を保存することを意味しません。具体的な必要性と、アクセス、保護、保持に関する特別な管理がない限り、機密性の高い断片は保存しないでください。

拒否、形式エラー、プロバイダー障害のメトリクスを追加し、セキュリティ上の問題と運用上の問題を区別できるようにします。個人データ、営業秘密、規制対象情報が含まれる場合、プロンプト全文、文書、応答を自動で保存しないでください。保持期間、アクセス、機密データのマスキングを定めます。十分であれば、ハッシュ、ID、構造化イベントを記録してください。ログが、機能で保護すべきコンテンツを露出させる新たな経路にならないようにします。

機能を有効化する前のチェックリスト

機能を有効化する前のチェックリスト — guía visual de DedicatedPHP
  • 各文書を取得する前に権限を確認していますか?
  • 送信するコンテキストは最小限で、範囲が制限され、信頼できない入力として扱われていますか?
  • ポリシーと業務ルールはモデルの外で適用されていますか?
  • ツールは制限され、操作ごとに認可を再確認していますか?
  • 応答を表示したり操作に変換したりする前に検証していますか?
  • 影響の大きい判断には人によるレビューまたは確認がありますか?
  • 再実行可能な敵対的テストと、保持期間を管理したログがありますか?

いずれかの答えが「いいえ」なら、そのギャップを解消するまで機能の範囲を制限するか、操作を提案モードにとどめてください。文書によるプロンプトインジェクションへの防御は、モデルが常にコンテンツを正しく解釈することに依存しません。モデルが誤っても、アクセスと操作の境界が機能し続けることが重要です。

これらのアイデアをあなたのプロジェクトに活用してみませんか?あなたのPHPプラットフォームについて話し合いましょう。
関連サービスを見る