Cors Wildcard in Django with Cockroachdb
Cors Wildcard in Django with Cockroachdb — how this specific combination creates or exposes the vulnerability
A CORS wildcard (Access-Control-Allow-Origin: *) in Django becomes high risk when backend services rely on CockroachDB as the data store. CockroachDB’s strong consistency and distributed SQL semantics do not enforce origin restrictions; they serve data if the SQL query executes. If Django views or an API layer do not validate origins before querying CockroachDB, the wildcard allows any origin to trigger queries that return sensitive rows.
Consider an endpoint that reads tenant data without origin checks:
SELECT id, email, ssn FROM users WHERE tenant_id = 'example';
With a CORS wildcard, any site can make authenticated requests (carrying cookies or tokens) and force the Django app to run these SQL statements against CockroachDB, effectively performing unauthorized data reads. The vulnerability is not in CockroachDB itself but in the lack of server-side origin enforcement combined with a permissive CORS policy.
Additionally, preflight requests can cause unnecessary load on CockroachDB if Django’s CORS handling is misconfigured to forward non-simple requests without early rejection. Unsafe consumption patterns (one of middleBrick’s 12 checks) arise when responses include sensitive fields like API keys or PII and the wildcard permits any downstream consumer to access them.
In a data-exfiltration scenario, an attacker site uses JavaScript to call the Django endpoint; the browser includes session cookies, CockroachDB returns private rows, and the wildcard allows the response to be read by the attacker. This maps to OWASP API Top 10 #1 (Broken Object Level Authorization) and can violate GDPR/HIPAA if personal data is exposed cross-origin.
Cockroachdb-Specific Remediation in Django — concrete code fixes
Remediation centers on strict CORS configuration, origin validation before database calls, and parameterized SQL against CockroachDB. Do not rely on frontend controls or network policies alone.
1. Configure Django CORS with explicit origins
Use django-cors-headers and avoid CORS_ALLOW_ALL_ORIGINS. Instead, specify origins and limit methods:
import os
CORS_ALLOWED_ORIGINS = [
"https://app.example.com",
"https://admin.example.com",
]
CORS_ALLOW_METHODS = [
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
]
CORS_ALLOW_HEADERS = [
"accept",
"authorization",
"content-type",
"x-csrftoken",
"x-requested-with",
]
# For production, also set:
# CORS_EXPOSE_HEADERS = ["X-Custom-Header"]
# CORS_ALLOW_CREDENTIALS = True
2. Validate origin in a middleware or view decorator before querying CockroachDB
Even with CORS settings, enforce origin checks at the application layer. Example decorator:
from django.http import HttpResponseForbidden
from django.utils.decorators import decorator_from_middleware
class OriginCheckMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
allowed = {"https://app.example.com", "https://admin.example.com"}
origin = request.META.get("HTTP_ORIGIN")
if origin and origin not in allowed:
return HttpResponseForbidden("Origin not allowed")
response = self.get_response(request)
return response
# In settings.py:
# MIDDLEWARE = [
# ...
# "yourapp.middleware.OriginCheckMiddleware",
# ]
3. Use CockroachDB-specific Django settings and safe queries
Ensure your database engine is set to CockroachDB’s PostgreSQL wire protocol. In settings.py, prefer connection parameters that match CockroachDB best practices (e.g., use sslmode=require). Use Django ORM or parameterized cursor calls to avoid SQL injection:
import django
from django.db import connection, ProgrammingError
def get_user_for_tenant(tenant_id, user_id):
# ORM approach (safe):
from myapp.models import User
try:
user = User.objects.using('cockroachdb').get(tenant_id=tenant_id, id=user_id)
return {"id": user.id, "email": user.email}
except User.DoesNotExist:
return None
# Raw parameterized example when needed:
def raw_tenant_query(tenant_id):
with connection.cursor() as cursor:
cursor.execute(
"SELECT id, email FROM users WHERE tenant_id = %s;",
[tenant_id]
)
return cursor.fetchall()
4. Principle of least privilege for the CockroachDB user
Create a database user for Django that has only the necessary rights (SELECT, INSERT, UPDATE on required tables). Avoid superuser or broad grants. This limits the impact if an origin bypass is discovered.
5. Continuous monitoring and scanning
Use middleBrick’s scans to detect CORS misconfigurations and unsafe consumption. The Pro plan enables continuous monitoring so future changes to origins or database logic trigger re-scans. Findings include remediation guidance tied to frameworks like OWASP API Top 10 and compliance mappings for GDPR/HIPAA.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |