Sql Injection in Flask with Cockroachdb
Sql Injection in Flask with Cockroachdb — how this specific combination creates or exposes the vulnerability
SQL Injection remains a critical risk for Flask applications that interact with CockroachDB, a distributed SQL database. The vulnerability arises when user-supplied input is concatenated into SQL statements rather than being handled through parameterized queries. In Flask, developers often construct queries using Python string formatting or concatenation, which allows an attacker to inject malicious SQL fragments. For example, a login route that builds a query like f"SELECT * FROM users WHERE email = '{email}' AND password = '{password}'" is directly exploitable regardless of the underlying database.
CockroachDB does not introduce unique injection mechanics compared to other SQL databases; however, its PostgreSQL wire protocol and SQL dialect mean that common injection patterns applicable to PostgreSQL also apply here. If a Flask app uses a CockroachDB driver such as psycopg or cockroachdb and builds queries unsafely, injection vectors like authentication bypass or data exfiltration are feasible. An attacker may supply input such as ' OR 1=1 -- to manipulate the logic of queries, bypassing intended filters.
Another contributing factor is the use of raw SQL in Flask routes without input validation or use of an ORM layer that enforces parameterization. Routes that accept identifiers (e.g., table or column names) via request parameters are especially risky if those identifiers are interpolated directly into SQL. Since CockroachDB supports standard SQL syntax, injected payloads can include UNION statements, subqueries, or destructive commands like DROP when safeguards are absent. The 12 security checks run by middleBrick include Input Validation and Authentication testing, which can identify these unsafe patterns in unauthenticated scans, highlighting SQL Injection risks specific to Flask and CockroachDB integrations.
Cockroachdb-Specific Remediation in Flask — concrete code fixes
To remediate SQL Injection in Flask when using CockroachDB, always use parameterized queries with placeholders and let the driver handle value escaping. Avoid string interpolation for any user-controlled data, including identifiers. Below are concrete, working examples using psycopg, which is compatible with CockroachDB.
Safe parameterized query with psycopg
import psycopg
from flask import Flask, request
app = Flask(__name__)
# Example: safe query using placeholders
@app.route('/user')
def get_user():
user_id = request.args.get('id')
conn = psycopg.connect("postgresql://user:password@host:26257/dbname")
with conn.cursor() as cur:
# Use %s placeholders; psycopg handles parameterization
cur.execute("SELECT email, role FROM users WHERE id = %s", (user_id,))
result = cur.fetchone()
conn.close()
return {'email': result[0], 'role': result[1]}
Safe dynamic table/column handling with allowlisting
ALLOWED_COLUMNS = {'email', 'username', 'created_at'}
@app.route('/search')
def search_users():
column = request.args.get('column', 'email')
term = request.args.get('term', '')
if column not in ALLOWED_COLUMNS:
return {'error': 'invalid column'}, 400
conn = psycopg.connect("postgresql://user:password@host:26257/dbname")
with conn.cursor() as cur:
# Use identifier placeholder via psycopg.Identifier for safe ordering
query = cur.mogrify("SELECT id, %I FROM users WHERE %I = %%s", (column, column, term))
cur.execute(query)
results = cur.fetchall()
conn.close()
return {'results': [dict(row) for row in results]}
Using an ORM (e.g., SQLAlchemy) with CockroachDB
from flask import Flask, request
from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker
app = Flask(__name__)
engine = create_engine('cockroachdb+psycopg://user:password@host:26257/dbname')
Session = sessionmaker(bind=engine)
@app.route('/items')
def list_items():
category = request.args.get('category')
session = Session()
# Use bound parameters; do not interpolate
stmt = text("SELECT name, price FROM items WHERE category = :category")
result = session.execute(stmt, {'category': category})
items = [dict(row) for row in result]
session.close()
return {'items': items}
These approaches ensure that user input is never interpreted as executable SQL. middleBrick scans can validate that such parameterization is consistently applied across endpoints, reducing SQL Injection risk and aligning findings with OWASP API Top 10 and compliance mappings.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |