HIGH llm data leakageflaskmongodb

Llm Data Leakage in Flask with Mongodb

Llm Data Leakage in Flask with Mongodb — how this specific combination creates or exposes the vulnerability

When a Flask application uses MongoDB as a data store and exposes endpoints that interact with LLMs—such as sending user input to an unauthenticated LLM endpoint or returning LLM-generated text—there is a risk of LLM data leakage. This occurs when model responses, system prompts, or intermediate data inadvertently expose sensitive information stored in MongoDB documents.

In this stack, a common pattern is for Flask to retrieve user records from MongoDB and include them in prompts sent to an LLM for summarization, classification, or assistance. If the prompt is constructed by directly interpolating MongoDB document fields (e.g., email, ssn, or internal identifiers) into the system or user messages, and the LLM response is returned to the client without filtering, sensitive data can leak through the LLM output.

For example, consider a Flask route that fetches a profile from MongoDB and sends it to an LLM to generate a support summary:

from flask import Flask, jsonify
from pymongo import MongoClient

app = Flask(__name__)
client = MongoClient('mongodb://localhost:27017/')
db = client['mydb']

@app.route('/summary/')
def user_summary(user_id):
    user = db.users.find_one({'_id': user_id})
    if not user:
        return jsonify({'error': 'not found'}), 404
    # Risky: sensitive fields included in prompt
    prompt = f"Summarize this user: {user['email']}, {user.get('ssn')}"
    llm_response = call_llm(prompt)  # hypothetical LLM call
    return jsonify({'summary': llm_response})

If the LLM echoes back the provided data or includes it in verbose responses, the email or ssn can be leaked to the caller or logged by the LLM provider. This is a form of LLM data leakage because sensitive MongoDB fields appear in the LLM context and may be reflected in outputs accessible to users or captured in logs.

Additionally, if the Flask app calls an unauthenticated or improperly scoped LLM endpoint, the system prompt itself might be exposed. The LLM/AI Security checks in middleBrick specifically test for system prompt leakage using regex patterns tailored to ChatML, Llama 2, Mistral, and Alpaca formats. Even if the prompt is built safely, a verbose LLM response can reveal internal instructions if the model is tricked through prompt injection or jailbreak techniques.

The combination of Flask routing, MongoDB document access, and LLM interaction amplifies risks when data flows from persistent storage into generative model inputs. Without strict input sanitization, output scanning, and prompt validation, sensitive MongoDB fields can travel through the LLM pipeline and become exposed in responses, logs, or error messages.

Mongodb-Specific Remediation in Flask — concrete code fixes

To prevent LLM data leakage in Flask applications using MongoDB, design data flows so that sensitive fields never enter LLM prompts and responses are filtered before being returned to clients. Apply the following concrete fixes and patterns.

1. Exclude sensitive fields from prompts

Never interpolate raw MongoDB documents into prompts. Instead, explicitly select only safe, non-sensitive fields and validate their content. For example:

def build_safe_prompt(user):
    # Only use non-sensitive fields
    return f"Summarize preferences for user with plan: {user.get('plan', 'unknown')} and last login: {user.get('last_login')}"

@app.route('/summary-safe/')
def user_summary_safe(user_id):
    user = db.users.find_one({'_id': user_id}, {'email': 0, 'ssn': 0})  # exclude sensitive fields
    if not user:
        return jsonify({'error': 'not found'}), 404
    prompt = build_safe_prompt(user)
    llm_response = call_llm(prompt)
    return jsonify({'summary': llm_response})

By projecting out email and ssn in the find_one query and using a dedicated prompt builder, sensitive data stays in MongoDB and does not enter the LLM context.

2. Sanitize and scan LLM responses

LLM outputs should be scanned for accidental inclusion of PII, API keys, or MongoDB identifiers before being returned. If your deployment includes output scanning (as in middleBrick’s LLM/AI Security checks), integrate a validation layer:

import re

PII_REGEXES = [
    re.compile(r'\b\d{3}-\d{2}-\d{4}\b'),  # SSN-like
    re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b'),  # email
]

def contains_pii(text):
    for pat in PII_REGEXES:
        if pat.search(text):
            return True
    return False

@app.route('/summary-guarded/')
def user_summary_guarded(user_id):
    user = db.users.find_one({'_id': user_id}, {'email': 0, 'ssn': 0})
    if not user:
        return jsonify({'error': 'not found'}), 404
    prompt = build_safe_prompt(user)
    llm_response = call_llm(prompt)
    if contains_pii(llm_response):
        return jsonify({'error': 'response blocked due to potential data leakage'}), 400
    return jsonify({'summary': llm_response})

This guards against reflections of MongoDB data and matches patterns commonly found in LLM leakage scenarios, such as SSNs and emails that might originate from stored documents.

3. Use authenticated LLM endpoints and strict system prompts

Ensure LLM endpoints are authenticated and avoid embedding secrets in system prompts that could be extracted via prompt injection probes. Validate and escape any dynamic content used in prompts, and prefer structured instructions over free-form concatenation.

4. Continuous monitoring and testing

Use tools like middleBrick to run LLM/AI Security checks against your endpoints. Its Active Prompt Injection testing (5 sequential probes) and System Prompt Leakage detection help identify weaknesses specific to Flask routes that feed MongoDB data into LLMs. Findings include guidance aligned with OWASP API Top 10 and compliance frameworks.

Related CWEs: llmSecurity

CWE IDNameSeverity
CWE-754Improper Check for Unusual or Exceptional Conditions MEDIUM

Frequently Asked Questions

How can I verify that sensitive MongoDB fields are excluded from LLM prompts in Flask?
Log the prompt content before sending it to the LLM and verify that fields like email or SSN are absent. Use unit tests that assert the prompt string does not match sensitive patterns, and inspect the MongoDB query projection to ensure sensitive fields are excluded.
What should I do if an LLM response appears to contain data from my MongoDB documents?
Immediately block the response, rotate any exposed credentials or keys, and audit your prompt construction and output filtering. Implement response scanning for PII and API keys, and refine prompt templates to avoid echoing raw database content.