flawopen.com/Référence/FastAPI SQL Injection
FastAPI empêche-t-il SQL Injection par défaut ?
Pydantic vérifie qu’une valeur correspond au type déclaré ; il ne réécrit pas le SQL et ne transforme pas une chaîne Python en paramètre de base de données. Un name: str validé reste un texte contrôlé par l’appelant. Imaginez que la validation vérifie l’étiquette d’un colis : elle confirme le type de valeur reçue, tandis que le paramétrage garde cette valeur séparée des instructions SQL. Gardez le modèle de requête fixe et transmettez les valeurs séparément via SQLAlchemy.
Exemple vulnérable et version sûre avec FastAPI
# Vérifier le type string ne rend pas l’entrée sûre dans la syntaxe SQL
@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 est un paramètre ; la valeur est transmise séparément
@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()
Ce que le paramétrage ne couvre pas
Un paramètre représente une valeur, pas un nom de table ou de colonne, un opérateur SQL ni un sens de tri. Si la requête doit choisir un champ de tri, associez le choix à une liste autorisée fixe d’expressions de colonnes SQLAlchemy ; n’insérez jamais directement la chaîne reçue dans le SQL. Le paramétrage ne remplace pas non plus l’autorisation : limitez les lignes que la personne peut lire et n’accordez au compte de base de données que les privilèges nécessaires à cet endpoint.
Liste de prévention
- ✓N’interpolez jamais les données de requête dans
text()de SQLAlchemy ni dans une chaîne SQL exécutée directement. - ✓Utilisez des paramètres nommés et transmettez leurs valeurs séparément, par exemple
db.execute(query, {"name": name}). - ✓Pour les choix dynamiques de table, colonne ou tri, associez l’entrée à une liste autorisée fixe d’expressions SQLAlchemy connues.
- ✓Vérifiez séparément l’autorisation au niveau des lignes et n’accordez au compte de base de données que les privilèges requis par l’endpoint.
- ✓Préférez les expressions
select()de SQLAlchemy lorsqu’elles conviennent ; l’ORM ne rend pas sûr un SQL brut vulnérable.
Références
- FastAPI — bases de données SQL (relationnelles)
- SQLAlchemy — transmission des paramètres et SQL textuel
- OWASP — prévention de SQL Injection