FlawOpen

flawopen.com/Referência/FastAPI SQL Injection

O FastAPI impede SQL Injection por padrão?

Guia de Python e APIs
Resposta curta

O Pydantic verifica se um valor corresponde ao tipo declarado; não reescreve SQL nem transforma uma string Python em parâmetro de banco de dados. Um name: str validado continua sendo texto controlado por quem chamou a API. Pense na validação como conferir a etiqueta de um pacote: ela identifica o tipo do conteúdo, enquanto a parametrização mantém o valor separado das instruções SQL. Mantenha o modelo da consulta fixo e passe os valores separadamente pelo SQLAlchemy.

Padrão vulnerável vs. seguro no FastAPI

VULNERÁVEL: a interpolação altera o texto SQL
# Verificar o tipo string não torna a entrada segura na sintaxe 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()
SEGURO: SQLAlchemy vincula o valor separadamente
# :name é um parâmetro; o valor é passado separadamente
@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()

O que a parametrização não protege

Um parâmetro vincula um valor, não o nome de uma tabela ou coluna, um operador SQL nem uma direção de ordenação. Se a requisição precisar escolher um campo de ordenação, mapeie a escolha para uma allow-list fixa de expressões de coluna do SQLAlchemy; nunca insira a string da requisição diretamente no SQL. A parametrização também não substitui autorização: restrinja quais linhas a pessoa pode ler e use uma conta de banco com apenas os privilégios necessários ao endpoint.

Checklist de prevenção

Referências

Veja também SQL Injection (CWE-89): como funciona e como evitar em todas as linguagens — flawopen.com GORM Raw SQL: evite injeção SQL em Go É suficiente escapar aspas contra SQL Injection? Usar um ORM basta para prevenir SQL Injection? Knex.js é seguro contra SQL Injection? MyBatis ${} vs #{}: evitar SQL Injection MySQLi vs PDO: prepared statements seguros