flawopen.com/SQL Injection in Python/SQLAlchemy

Is SQLAlchemy's text() safe?

Reference page — draft, pending review
Short answer

Yes, when you use it with bound parameters. Unsafe the moment the SQL string itself is built with an f-string before being wrapped in text().

UNSAFE
stmt = text(
  f"SELECT * FROM users WHERE id = {user_id}"
)
conn.execute(stmt)
SAFE
stmt = text(
  "SELECT * FROM users WHERE id = :id"
)
conn.execute(stmt, {"id": user_id})

The rule

text() just wraps a raw SQL string — it doesn't make anything safe by itself. Safety comes entirely from passing values through the params dict as the second argument to execute(), exactly the same discipline as plain DB-API cursor.execute().

How to check your codebase

grep -rn "text(f\"" --include="*.py" .

FAQ

Is the standard ORM query API (select(), Session.query()) safe?

Yes — SQLAlchemy's Core and ORM query builders parameterize automatically. The risk is isolated entirely to text() and raw connection execution.

References