RAG セキュリティ: 完全ガイド
Securing Retrieval-Augmented Generation systems against document poisoning, retrieval manipulation, and embedding attacks
Updated: August 2026 • OWASP LLM08 の一部
RAG とは何ですか?
Retrieval-Augmented Generation (RAG) is an AI architecture that combines large language models with external knowledge retrieval. Enterprise LLM deployments now use RAG extensively, making its security critical.
1。ユーザー クエリ
ユーザーがシステムに質問またはプロンプトを送信
2. 埋め込み
クエリはベクトル埋め込みに変換されます
3.取得
ベクター DB から取得した類似ドキュメント
4。拡張
プロンプトに取得したコンテキストを追加
5.世代
LLM がコンテキストを使用して応答を生成
信頼のパラドックス
RAG systems have a fundamental security flaw: user queries are treated as untrusted input, but retrieved context is implicitly trusted - even though both enter the same prompt. This creates a significant attack surface that traditional security doesn't address.
攻撃ベクトル
1。ドキュメントポイズニング
悪意のあるコンテンツの挿入ナレッジベースに保存されているドキュメントに保存されます。
仕組み
- 攻撃者による悪意のあるドキュメントのアップロードまたは挿入
- ドキュメントはベクター DB に埋め込まれ、保存されます
- 関連するクエリが作成されると、毒されたドキュメントが取得されます
- LLM は悪意のあるコンテキストを応答に組み込む
影響
- 90% success たった 5 つの有害文書で
- 数百万のドキュメントが含まれるデータベースでも動作
- 有害、偏った、または不正確な出力を引き起こす可能性がある
- 展開後の検出が困難
2.取得操作
どのドキュメントを取得して出力に影響を与えるかを操作します。
仕組み
- 攻撃者は特定の取得をトリガーするクエリを作成
- ランキング アルゴリズムの弱点を悪用
- セマンティックな類似性を使用して取得をハイジャックする
- 共有システムでのユーザー間操作
影響
- 攻撃者が制御するコンテンツの強制取得
- 正当なコンテンツを抑制可能
- 対象を絞った操作を有効にする
- 検索品質の信頼を打ち破る
3.埋め込み反転
ベクトル埋め込みからの元のデータの復元。
仕組み
- 攻撃者がベクター データベースにアクセス
- 埋め込みに反転技術を使用します
- ベクトルから元のテキストを再構築
- 機密の埋め込みデータを回復
影響
- Recover 50-70% of input words
- 埋め込み内の機密データの公開
- プライバシー違反
- コンプライアンス問題 (GDPR など)
4.クロステナント攻撃
マルチテナント システムでの共有 RAG インフラストラクチャの悪用。
仕組み
- 攻撃者は共有システムの 1 テナント
- 他のテナントに影響を与えるコンテンツの挿入
- 共有ベクトル データベースを悪用
- 他のテナントからデータを取得
影響
- テナント間のデータ漏洩
- 競合他社データへの不正アクセス
- コンプライアンス違反
- 風評被害
現実世界の CVE
RAG システムの文書化された脆弱性
| CVE ID | 製品 | 説明 | 重大度 | CVSS |
|---|---|---|---|---|
CVE-2025-68700 |
RAGFlow | RCE via Canvas CodeExec component - untrusted data parsed with eval() | Critical | 9.1 |
CVE-2025-69286 |
RAGFlow | Insecure API key generation allows mutual token derivation (authentication bypass) | Critical | 8.9 |
CVE-2025-25282 |
RAGFlow | IDOR vulnerability allowing cross-tenant access and unauthorized user addition | High | 8.1 |
CVE-2025-69286 |
RAGFlow | Token generation using same URLSafeTimedSerializer for API keys | High | 8.9 |
GHSA-8xw3-v6c2-j84j |
RAGFlow | RCE via stdout parsing in CodeExec component | High | 8.5 |
防御戦略
1. 取り込みフェーズのセキュリティ
文書の検証
- すべてのドキュメントでマルウェアをスキャン
- ドキュメントの形式と構造を検証する
- 不審なコンテンツ パターンをチェックする
- 許可されるドキュメント タイプを制限する
コンテンツ フィルタリング
- 埋め込む前に PII を削除
- 機密データ パターンのフィルタリング
- 既知の悪意のあるパターンのブロック
- 許可/ブロック リストの実装
アクセス制御
- ドキュメントのソースの検証
- 取り込み用の RBAC の実装
- すべてのアップロードの監査証跡
- 新しいドキュメントの隔離
2。取得段階のセキュリティ
クエリの無害化
- ユーザー クエリを検証およびサニタイズする
- インジェクション試行を検出
- クエリの複雑さを制限
- レート制限
取得フィルタリング
- 再ランキング セキュリティを実装
- 信頼できるソースとの相互参照
- 異常な取得パターンを検出します
- ドキュメントの数を制限する
マルチテナント分離
- 個別のベクター名前空間
- 厳格なテナント境界
- クロステナント クエリ防止
- テナントごとの暗号化
3.生成段階のセキュリティ
出力検証
- LLM出力を検証
- 挿入されたコンテンツをチェックする
- ソースとのファクトチェック
- コンテンツ フィルタリング
コンテキストの検証
- 取得したコンテンツの信頼性を検証します
- 操作の試みを検出
- 異常なコンテキスト パターンにフラグを立てる
- すべてのコンテキストの使用状況をログに記録
人間参加型
- 機密性の高い出力を確認します
- リスクの高いアクションを承認
- 手動オーバーライド機能
- エスカレーション パス
4.データ セキュリティ
暗号化
- 保存中のベクトルを暗号化
- 転送中のデータに対する TLS
- キー管理のベストプラクティス
- 準同型暗号化を検討する
ベクター DB セキュリティ
- 強力な認証
- ネットワークの分離
- 定期的なセキュリティ監査
- パッチ管理
プライバシー保護
- データの最小化
- PII の検出と削除
- 保持ポリシー
- 削除の権利のサポート
テスト方法
RAG セキュリティ テスト チェックリスト
- ドキュメント インジェクション テスト
- 取得操作テスト
- 反転試行の埋め込み
- テナント間分離テスト
- PII 漏洩テスト
- コンテキスト オーバーフロー テスト
- ランキング操作テスト
- 認証バイパス テスト
- API インジェクション テスト
- サービス拒否テスト
- データ漏洩テスト
- コンプライアンス監査
テスト ツール
コード例
文書検証の例
```python
import re
from typing import List
class RAGDocumentValidator:
SUSPICIOUS_PATTERNS = [
r"ignore previous instructions",
r"system prompt:",
r"{{.*}}",
r"you are now dan",
]
PII_PATTERNS = [
r"\b\d{3}-\d{2}-\d{4}\b", # SSN
r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b", # Email
r"\b\d{16}\b", # Credit card
]
def validate_document(self, content: str) -> dict:
"""Validate document before embedding."""
warnings = []
blocked = False
# Check for suspicious patterns
for pattern in self.SUSPICIOUS_PATTERNS:
if re.search(pattern, content, re.IGNORECASE):
warnings.append(f"Suspicious pattern: {pattern}")
blocked = True
# Check for PII
for pattern in self.PII_PATTERNS:
if re.search(pattern, content):
warnings.append(f"PII detected: {pattern}")
return {
"valid": not blocked,
"warnings": warnings,
"pii_detected": len([w for w in warnings if "PII" in w]) > 0
}
```