Como Corrigir SQL Inseguro Escrito por IA
Agentes de IA criam consultas SQL com interpolação de strings em vez de instruções parametrizadas, introduzindo vulnerabilidades de injeção SQL no código de banco de dados em produção.
O agente recorre a literais de modelo para construir consultas SQL, criando vetores clássicos de injeção SQL que parecem funcionar bem em testes, mas são exploráveis em produção.
O sintoma
Valores controlados pelo usuário são interpolados diretamente em uma string SQL.
// WRONG — SQL injection vulnerabilityasync function getUserByEmail(email: string) { const result = await db.query( `SELECT * FROM users WHERE email = '${email}'` // ^^^^^^^ attacker-controlled ); return result.rows[0];}
// Attacker input: ' OR '1'='1// Resulting query: SELECT * FROM users WHERE email = '' OR '1'='1'// Returns every row in the table.Por que isso acontece
Literais de modelo são a ferramenta mais natural para construir strings em JavaScript, e muitos exemplos de tutoriais com os quais o modelo foi treinado os utilizam para SQL sem parametrização. O agente também não modela entradas adversárias — ele imagina dados bem formados passando.
Como identificar
- Strings SQL que contêm interpolações
${...}. - Funções de consulta que aceitam entrada do usuário e a passam para um auxiliar de consulta bruta sem um array de parâmetros separado.
db.query(sql)chamado com um único argumento em vez dedb.query(sql, [params]).- Padrões
LIKE '%${term}%'.
Como corrigir
Sempre use consultas parametrizadas. O driver do banco de dados lida com o escape; seu código nunca toca em citações.
// CORRECT — parameterized query (node-postgres / pg)async function getUserByEmail(email: string) { const result = await db.query( "SELECT id, name, email FROM users WHERE email = $1", [email] // second argument: params array ); return result.rows[0] ?? null;}
// CORRECT — with Postgres.js (template tag)async function searchUsers(term: string) { return sql`SELECT id, name FROM users WHERE name ILIKE ${"%" + term + "%"}`; // postgres.js automatically parameterizes template expressions}[ ] No ${...} inside raw SQL strings — use $1/$2 placeholders instead[ ] Every db.query() call passes user input via the params array, not the SQL string[ ] Use an ORM (Prisma, Drizzle) or query builder for complex queries[ ] LIKE wildcards are appended in the param value, not concatenated into the SQL[ ] Run sqlfluff or a SQL linter in CI to catch interpolated stringsPrompt de Correção
This SQL query uses string interpolation with user-supplied values, which is aSQL injection vulnerability. Rewrite every raw query to use parameterizedstatements ($1, $2 placeholders for pg, or the tagged template literal form forpostgres.js). Never interpolate variables directly into SQL strings. If thequery is complex, migrate it to Prisma or Drizzle ORM instead.Teste
# Detect template literal interpolation inside SQL-looking stringsgrep -rn 'query(`\|sql`\|execute(`' --include="*.ts" --include="*.tsx" . \ | grep '\${' \ | grep -v "node_modules" \ && echo "FAIL: interpolated SQL found" || echo "OK"