HIGH llm data leakageflaskapi keys

Llm Data Leakage in Flask with Api Keys

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

LLM data leakage in a Flask application often occurs when API keys are handled in ways that expose them in model inputs, logs, or responses. Flask routes that forward user content to external LLM endpoints may inadvertently include sensitive keys in prompts if the application concatenates user data with credentials or configuration values. For example, constructing a prompt from request parameters, session tokens, or debug information can inject key material into the context sent to the LLM, which then may echo the keys in its output or expose them through error messages.

Because LLM data leakage detection is a unique capability of middleBrick, it specifically checks for system prompt leakage patterns across common LLM formats, including ChatML and others. When Flask-based services use unauthenticated LLM endpoints or expose endpoints that accept user-controlled inputs used directly as prompts, the scanner can detect whether keys or other sensitive configuration appear in the model context or outputs. Attack patterns such as prompt injection can coax the LLM to reveal injected configuration lines, while output scanning looks for API keys or PII returned in responses. Insecure handling of environment variables, combined with verbose error reporting in Flask, can amplify the risk by exposing stack traces that include key values.

The risk is elevated when Flask routes do not enforce strict input validation or when developers embed keys in code or configuration files that are loaded into the request context. Cross-referencing OpenAPI specifications with runtime findings allows middleBrick to identify mismatches where declared authentication requirements do not match actual behavior, such as an endpoint that claims to require an API key but forwards requests unauthenticated to an LLM service. This mismatch can lead to unauthenticated LLM endpoint detection, where endpoints intended to be protected inadvertently expose functionality that can be abused to probe or extract model behavior and data.

Api Keys-Specific Remediation in Flask — concrete code fixes

To remediate API key leakage in Flask, ensure keys are never incorporated into prompts, logs, or responses, and are accessed only through secure configuration management. Use environment variables or a secrets manager, and read them once at startup rather than per request. Validate and sanitize all inputs before they are passed to any LLM client, and avoid echoing user input in error messages or debug output.

Below are concrete, secure code examples for handling API keys in Flask:

import os
from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

# Secure: read key from environment at startup, not per request
API_KEY = os.environ.get('EXTERNAL_LLM_API_KEY')
if not API_KEY:
    raise RuntimeError('Missing required environment variable: EXTERNAL_LLM_API_KEY')

@app.route('/query', methods=['POST'])
def query_llm():
    data = request.get_json()
    user_prompt = data.get('prompt', '').strip()

    # Validate input: enforce length and character rules to reduce injection risk
    if not user_prompt or len(user_prompt) > 2000:
        return jsonify({'error': 'Invalid prompt'}), 400

    # Build the request to the external LLM without including API key in prompt
    headers = {'Authorization': f'Bearer {API_KEY}'}
    payload = {
        'model': 'gpt-4o-mini',
        'messages': [{'role': 'user', 'content': user_prompt}]
    }

    try:
        resp = requests.post(
            'https://api.example.com/v1/chat/completions',
            json=payload,
            headers=headers,
            timeout=10
        )
        resp.raise_for_status()
        result = resp.json()
        # Ensure the response does not contain key material; safe extraction
        content = result.get('choices', [{}])[0].get('message', {}).get('content', '')
        return jsonify({'response': content})
    except requests.RequestException as e:
        # Do not expose API key or raw error details that may contain configuration
        app.logger.error('LLM request failed: %s', str(e))
        return jsonify({'error': 'Service unavailable'}), 502

if __name__ == '__main__':
    app.run()

Additional practices include rotating keys regularly, using application-layer secrets management, and monitoring outbound requests to detect anomalies. The Pro plan of middleBrick supports continuous monitoring and can be integrated into CI/CD pipelines via the GitHub Action to fail builds if risk scores exceed your defined thresholds, helping to catch regressions before deployment.

Related CWEs: llmSecurity

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

Frequently Asked Questions

How does middleBrick detect LLM data leakage in Flask APIs?
middleBrick runs unauthenticated scans that test input validation, error handling, and prompt injection paths. It checks for system prompt leakage patterns, actively probes endpoints with prompt injection sequences, scans LLM outputs for API keys and PII, and cross-references OpenAPI specs with runtime behavior to identify mismatches that could expose keys.
Can the free tier of middleBrick detect API key leakage in Flask applications?
Yes, the free tier allows 3 scans per month and includes the full set of 12 security checks, including LLM/AI Security tests that detect system prompt leakage and output scanning for API keys. This enables detection of key exposure risks without cost, though continuous monitoring and CI/CD integration are available in higher tiers.