flawopen.com/Reference/FastAPI SQL Injection
Does FastAPI prevent SQL Injection by default?
Pydantic checks whether a value matches the declared input type; it does not rewrite SQL or turn a Python string into a database parameter. A validated name: str is still caller-controlled text. Think of validation as checking the label on a parcel: it confirms what kind of value arrived, while parameter binding seals the value outside the SQL instruction sheet. Keep the SQL template fixed and pass values separately through SQLAlchemy.
Vulnerable vs. safe FastAPI pattern
# A string type check does not make input safe inside SQL syntax
@app.get("/users")
def get_users(name: str, db: Session = Depends(get_db)):
query = text(f"SELECT * FROM users WHERE name = '{name}'")
return db.execute(query).fetchall()
# :name is a bind parameter; the value is passed separately
@app.get("/users")
def get_users(name: str, db: Session = Depends(get_db)):
query = text("SELECT * FROM users WHERE name = :name")
return db.execute(query, {"name": name}).fetchall()
What parameter binding does not cover
A bound parameter represents a data value, not a table name, column name, SQL operator, or sort direction. If a request must choose a sort field, map the choice to a fixed allow-list of SQLAlchemy column expressions; never splice the raw request string into SQL. Parameterization also does not replace authorization: constrain which rows the caller may read, and use a database account with only the privileges the endpoint needs.
Prevention checklist
- ✓Never interpolate request data into SQLAlchemy
text()or a raw database execution string. - ✓Use named bind parameters and pass their values separately, such as
db.execute(query, {"name": name}). - ✓For dynamic table, column, or sort choices, map input to a fixed allow-list of known SQLAlchemy expressions.
- ✓Check row-level authorization independently and grant the database account only the privileges the endpoint needs.
- ✓Prefer SQLAlchemy
select()expressions when they express the query clearly; ORM use does not make unsafe raw SQL safe.
References
- FastAPI — SQL (Relational) Databases
- SQLAlchemy — Sending Parameters and textual SQL
- OWASP — SQL Injection Prevention Cheat Sheet