Cors Wildcard in Flask with Cockroachdb
Cors Wildcard in Flask with Cockroachdb — how this specific combination creates or exposes the vulnerability
A CORS wildcard in a Flask application that serves data from Cockroachdb can unintentionally expose backend APIs to any origin. In Flask, developers sometimes use Access-Control-Allow-Origin: * to simplify development, but when the application relies on database-level tenant isolation or user-specific data in Cockroachdb, the wildcard allows any website to make authenticated requests on behalf of users.
Consider a Flask route that queries Cockroachdb using an identifier passed from the client:
import psycopg2
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/api/user/orders")
def user_orders():
user_id = request.args.get("user_id")
conn = psycopg2.connect(
host="localhost",
port 26257,
user="app_user",
password="secret",
database="orders_db"
)
cur = conn.cursor()
cur.execute("SELECT order_id, total FROM orders WHERE user_id = %s", (user_id,))
rows = cur.fetchall()
cur.close()
conn.close()
return jsonify(rows)
If the Flask app sets app.config['CORS_HEADERS'] = 'Access-Control-Allow-Origin: *' and does not validate the user_id against the authenticated session or enforce tenant boundaries, an attacker can craft a page that calls this endpoint with arbitrary user_id values. Because Cockroachdb stores data across nodes with strong consistency, the query will return data if the identifier is valid, leading to unauthorized data access across what should be isolated tenant datasets.
This becomes a BOLA/IDOR vector combined with a misconfigured CORS policy. The wildcard allows any origin to invoke the endpoint, and Cockroachdb’s reliability does not enforce origin-level authorization. An attacker does not need to exploit a bug in Cockroachdb itself; they exploit the lack of origin validation in Flask and the absence of per-request identity checks against the database rows.
In a real assessment using middleBrick, such a configuration would appear as a finding in the CORS check and the Property Authorization check, with remediation guidance to replace the wildcard with specific origins and to enforce data-level authorization on every database query.
Cockroachdb-Specific Remediation in Flask — concrete code fixes
Remediation centers on two controls: strict CORS configuration and robust data access checks that respect identity and tenant boundaries. Do not rely on Cockroachdb’s SQL correctness alone; enforce authorization in the application layer before forming queries.
First, configure CORS to allow only known origins. Using flask-cors is a practical approach:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources={r"/api/*": {"origins": ["https://app.example.com", "https://admin.example.com"]}})
Second, ensure each Cockroachdb query includes the authenticated user’s identity or tenant context. If your authentication layer provides a current_user_id, use it to scope queries:
import psycopg2
from flask import Flask, request, jsonify, g
def get_db_connection():
return psycopg2.connect(
host="localhost",
port=26257,
user="app_user",
password="secret",
database="orders_db"
)
@app.route("/api/user/orders")
def user_orders():
# Assume g.current_user_id is set by an auth middleware
user_id = g.current_user_id
conn = get_db_connection()
cur = conn.cursor()
cur.execute("SELECT order_id, total FROM orders WHERE user_id = %s", (user_id,))
rows = cur.fetchall()
cur.close()
conn.close()
return jsonify(rows)
For multi-tenant deployments where Cockroachdb uses a shared schema, include a tenant identifier in every query:
@app.route("/api/tenant/data")
def tenant_data():
tenant_id = g.current_tenant_id
search_key = request.args.get("key")
conn = get_db_connection()
cur = conn.cursor()
cur.execute(
"SELECT value FROM tenant_data WHERE tenant_id = %s AND key = %s",
(tenant_id, search_key)
)
row = cur.fetchone()
cur.close()
conn.close()
if row is None:
return jsonify({"error": "not found"}), 404
return jsonify(row)
These patterns ensure that even with a highly available Cockroachdb backend, the application does not leak data across users or tenants. Combine this with input validation and parameterized queries to prevent injection, and your Flask service will align better with the checks performed by middleBrick’s Property Authorization and Input Validation modules.
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 |