HIGH llm data leakagedjangomutual tls

Llm Data Leakage in Django with Mutual Tls

Llm Data Leakage in Django with Mutual Tls — how this specific combination creates or exposes the vulnerability

LLM data leakage in a Django service that uses mutual TLS (mTLS) occurs when an application handling mTLS client authentication also exposes an endpoint or background process that sends user or system data to an LLM without proper safeguards. In this combination, the presence of mTLS may create a false sense of strict access control, leading developers to assume all downstream communication is equally protected. This assumption can result in insufficient input validation, overly verbose error messages, or insecure logging practices that expose sensitive data to the LLM.

For example, if Django views authenticate clients with client certificates and then forward request metadata (such as usernames, roles, or session identifiers) to an LLM for analysis or summarization, that data can be leaked through prompts or retrieved via indirect prompt injection techniques. The LLM security checks provided by middleBrick detect system prompt leakage across formats such as ChatML and Llama 2, as well as active prompt injection probes including system prompt extraction and data exfiltration. These probes can surface paths where Django code inadvertently passes sensitive context into LLM queries, especially when error handling or debugging information is included in prompts.

Mutual TLS does not protect data once it enters the application layer; if Django code constructs LLM prompts from request bodies, query parameters, or headers without sanitization, sensitive information may be included in model inputs. This risk is compounded when Django logs contain PII or credentials and those logs are later ingested by LLM tools for analysis. middleBrick’s output scanning for PII, API keys, and executable code in LLM responses helps identify whether leaked data appears in model outputs, while excessive agency detection can reveal agent-style tool usage patterns that propagate sensitive context beyond intended boundaries.

In architectures where Django acts as a backend gateway for unauthenticated LLM endpoints, mTLS secures channel-level identity but does not prevent application-layer leakage into prompts. The LLM endpoint may receive requests that include API keys or internal references embedded in Django-rendered templates or JSON payloads. Continuous monitoring and scanning, such as that available in the Pro plan with configurable schedules and Slack or Teams alerts, can highlight trends where specific views or background tasks repeatedly expose sensitive content to LLMs.

middleBrick’s OpenAPI/Swagger spec analysis, which resolves full $ref references across 2.0, 3.0, and 3.1 specs, can highlight endpoints that accept or emit data potentially forwarded to LLM services. When combined with runtime findings, this provides visibility into how data flows from mTLS-authenticated Django views into LLM interactions, enabling teams to pinpoint where prompt injection, PII exposure, or credential leakage may occur.

Mutual Tls-Specific Remediation in Django — concrete code fixes

Remediation focuses on preventing sensitive data from reaching the LLM and hardening Django’s handling of mTLS contexts. Ensure that any data derived from the client certificate or request is sanitized before inclusion in LLM prompts. Use explicit allowlists for fields that can be safely forwarded, and remove or hash identifiers that are not required for LLM processing.

Below are concrete Django code examples that demonstrate secure integration with mTLS while avoiding LLM data leakage.

1. Configure mTLS in Django settings

Set up Django to require and validate client certificates without relying on them for data handling decisions.

SECURE_SSL_REDIRECT = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True

# paths to your CA, server cert, and server key
WSGI_APPLICATION = 'myproject.wsgi.application'
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

# Example using django-sslserver for local development; in production, handle mTLS at the load balancer or reverse proxy
# and pass validated metadata via headers, not client certificates, to application logic.

2. Sanitize data before LLM calls

Create a utility that extracts only safe, non-sensitive information from the request and certificate metadata before constructing prompts.

import re
import hashlib
from typing import Any, Dict

def sanitize_for_llm(request) -> Dict[str, Any]:
    """
    Build a minimal, safe context for LLM prompts by excluding PII,
credentials, and certificate details that should not be forwarded.
    """
    safe_context = {}

    # Example: include only a hashed, non-reversible role claim
    role = request.META.get('SSL_CLIENT_S_DN_CN', 'unknown')
    safe_context['role_hash'] = hashlib.sha256(role.encode()).hexdigest()[:16]

    # Explicitly allowlisted fields from cleaned request data
    if hasattr(request, 'data'):
        # Only forward fields that are explicitly safe
        for field in ('analysis_type', 'locale'):
            if field in request.data:
                safe_context[field] = request.data[field]

    # Remove any PII or identifiers that may be present in headers or logs
    return safe_context

3. Use safe prompt construction in views

In your Django view, use the sanitized context and avoid concatenating raw request data into prompts.

from django.http import JsonResponse
from .llm_utils import call_llm_with_safety_checks
from .sanitize import sanitize_for_llm

def analyze_view(request):
    safe_context = sanitize_for_llm(request)

    prompt = (
        f"Analyze the following anonymized data: {safe_context.get('analysis_type')}. "
        f"Role category (hashed): {safe_context.get('role_hash')}. "
        f"Do not include any raw identifiers or credentials in the output."
    )

    result = call_llm_with_safety_checks(prompt)
    return JsonResponse({'result': result})

4. Secure LLM utility with safety checks

A helper that logs minimal metadata and applies output scanning concepts (similar to middleBrick’s PII and code detection) before returning results.

import logging
from typing import Any

logger = logging.getLogger(__name__)

def call_llm_with_safety_checks(prompt: str) -> Any:
    """
    Placeholder for actual LLM invocation.
    Ensure the implementation avoids logging prompt contents and
    applies output validation for PII, API keys, and code.
    """
    # Example: integrate with your LLM client here
    # response = client.chat(messages=[{'role': 'user', 'content': prompt}])
    # Simulated response
    response = {'content': 'Analysis result with no sensitive data.'}

    # Basic safety: ensure no obvious secrets in output (conceptual)
    if 'api_key' in response.get('content', '').lower():
        logger.warning('Potential API key detected in LLM output')
        response['content'] = 'Redacted due to security policy.'

    return response

5. Logging and monitoring hygiene

Ensure Django logging does not capture sensitive request details that could be forwarded to LLMs or stored insecurely.

import logging

logger = logging.getLogger(__name__)

def safe_log_request_summary(request):
    logger.info(
        'Request processed',
        extra={
            'path': request.path,
            'method': request.method,
            'role_hash': hashlib.sha256(
                request.META.get('SSL_CLIENT_S_DN_CN', 'unknown').encode()
            ).hexdigest()[:16],
        },
    )

Related CWEs: llmSecurity

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

Frequently Asked Questions

Does mutual TLS prevent LLM data leakage in Django?
No. Mutual TLS secures channel identity but does not prevent application-layer leakage. Sensitive data included in prompts, logs, or error messages can still be exposed to LLMs; mitigation requires input sanitization and safe prompt design.
How can I verify my Django setup does not leak data to LLMs?
Use scanning tools that include LLM-specific checks, such as active prompt injection probes and output scanning for PII and API keys. Review prompt construction to ensure only sanitized, allowlisted fields are used, and avoid logging raw certificate or request data.