Cómo corregir el SQL inseguro escrito por IA
Los agentes de IA crean consultas SQL con interpolación de cadenas en lugar de declaraciones parametrizadas, introduciendo vulnerabilidades de inyección SQL en el código de base de datos en producción.
El agente recurre a literales de plantilla para construir consultas SQL, creando vectores clásicos de inyección SQL que parecen funcionar bien en las pruebas pero son explotables en producción.
El síntoma
Los valores controlados por el usuario se interpolan directamente en una cadena 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 qué ocurre
Los literales de plantilla son la herramienta más natural para construir cadenas en JavaScript, y muchos ejemplos de tutoriales en los que se entrenó el modelo los usan para SQL sin parametrización. El agente tampoco modela entradas adversarias: imagina datos bien formados que pasan a través.
Cómo detectarlo
- Cadenas SQL que contienen interpolaciones
${...}. - Funciones de consulta que aceptan entrada del usuario y la pasan a un ayudante de consulta sin un arreglo de parámetros separado.
db.query(sql)llamado con un solo argumento en lugar dedb.query(sql, [params]).- Patrones
LIKE '%${term}%'.
Cómo corregirlo
Siempre use consultas parametrizadas. El controlador de base de datos maneja el escape; su código nunca toca las comillas.
// 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 stringsIndicación de corrección
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.Prueba
# 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"