HIGH sql injectiondjangomutual tls

Sql Injection in Django with Mutual Tls

Sql Injection in Django with Mutual Tls — how this specific combination creates or exposes the vulnerability

SQL injection in Django occurs when untrusted input is concatenated into database queries, allowing an attacker to alter query logic. Django’s ORM largely protects against classic SQLi when querysets are used as intended, but raw SQL execution via cursor.execute() or Manager.raw() without parameterization remains risky. Mutual TLS (mTLS) secures transport layer authentication—client certificates are validated before application logic runs—but it does not change how queries are built. The combination can expose SQL injection because mTLS may give an attacker implicit trust or access to endpoints that use raw queries, encouraging a false sense of security.

Consider a Django view that authenticates a request with mTLS (client certificate validated) and then builds SQL dynamically:

from django.db import connection
def search_users(request):
    name = request.GET.get('name', '')
    with connection.cursor() as cursor:
        cursor.execute(f'SELECT id, email FROM auth_user WHERE name = \'{name}\'')
        rows = cursor.fetchall()
    return JsonResponse(list(rows), safe=False)

Even with mTLS ensuring the client is who they claim to be, the name parameter is interpolated directly into the SQL string, enabling injection (e.g., name=' OR 1=1 --). mTLS does not mitigate injection; it only authenticates the connection. Additionally, mTLS endpoints often expose administrative or sensitive operations that developers might treat as trusted, leading to skipped input validation. OWASP API Top 10 A03:2023 (Injection) remains relevant, and frameworks like Django require disciplined use of parameterized queries regardless of transport protections.

Key risk pattern: using mTLS to gate raw SQL routes without enforcing strict input validation and query parameterization. Attackers who obtain or spoof a valid client certificate can directly exploit SQL injection to extract, modify, or delete data. This highlights why transport-layer controls must be complemented with secure coding practices.

Mutual Tls-Specific Remediation in Django — concrete code fixes

Remediation centers on avoiding raw SQL interpolation and using parameterized queries even when mTLS is in place. Below are concrete, safe patterns for Django with mTLS examples.

1. Safe parameterized query with mTLS client validation

Use connection.cursor() with parameterized queries. Django’s cursor.execute(sql, params) supports passing parameters separately, which ensures proper escaping.

from django.db import connection
def search_users(request):
    name = request.GET.get('name', '')
    # mTLS validation would occur earlier (e.g., via request attributes or middleware)
    with connection.cursor() as cursor:
        cursor.execute('SELECT id, email FROM auth_user WHERE name = %s', [name])
        rows = cursor.fetchall()
    return JsonResponse([dict(row) for row in rows], safe=False)

2. Using Django’s ORM to avoid raw SQL entirely

Prefer the ORM, which automatically parameterizes queries. This approach is robust and eliminates injection risk for standard lookups.

from django.contrib.auth.models import User
def search_users_orm(request):
    name = request.GET.get('name', '')
    users = User.objects.filter(name=name)
    return JsonResponse(list(users.values('id', 'email')), safe=False)

3. Enforcing mTLS and safe query practices together (middleware example)

You can implement a simple middleware to validate client certificates and ensure safe handling downstream. This example assumes a certificate attribute is set on the request after mTLS verification.

import ssl
from django.http import JsonResponse
class MutualTlsValidationMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
    def __call__(self, request):
        # In production, use proper cert validation via your web server (e.g., Nginx/Apache)
        # and set request attributes after successful verification.
        if not hasattr(request, 'client_cert_valid') or not request.client_cert_valid:
            return JsonResponse({'error': 'Client certificate required'}, status=403)
        return self.get_response(request)

4. Example with explicit query parameterization and logging

import logging
logger = logging.getLogger(__name__)
def get_user_by_id(request, user_id):
    # Assume user_id is validated as integer
    try:
        uid = int(user_id)
    except ValueError:
        return JsonResponse({'error': 'Invalid user ID'}, status=400)
    with connection.cursor() as cursor:
        cursor.execute('SELECT id, email FROM auth_user WHERE id = %s', [uid])
        row = cursor.fetchone()
    if row:
        return JsonResponse(dict(zip([col[0] for col in cursor.description], row)))
    return JsonResponse({'error': 'Not found'}, status=404)

These examples emphasize parameterization and ORM usage regardless of mTLS. mTLS secures who can connect, but SQL safety must be enforced in code. Findings from scans will flag raw SQL interpolation as high severity, with remediation guidance to use parameterized queries or ORM filters.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Does mutual TLS prevent SQL injection in Django?
No. Mutual TLS secures transport and client authentication but does not affect query construction. SQL injection must be prevented through parameterized queries or ORM usage.
How can I verify my Django endpoints are safe while using mTLS?
Use a security scanner like middleBrick to test unauthenticated attack surface and raw query patterns. Ensure all database interactions use parameterized queries or the Django ORM, and review code for any string interpolation in SQL.