Inyección SQL: nunca pegues texto de usuario en una consulta
Las consultas de este sitio las escribes tú a propósito. En una aplicación, parte del texto de una consulta viene de un formulario, una URL o una API. Si ese texto se pega en el SQL, un visitante puede cambiar lo que hace la sentencia. Esta página muestra el error en la base de la panadería y luego la corrección. No es una guía para atacar otros sistemas.
La consulta que querías
Supón que una app busca un cliente por apellido. El SQL previsto filtra solo por ese nombre.
SELECT first_name, last_name FROM customers WHERE last_name = 'Lopez' ORDER BY customer_id;
Resultado: Ana Lopez, una fila.
Qué puede hacer el texto pegado
Si la app construye la sentencia como `WHERE last_name = '` más lo que escribió el visitante más `'`, entonces meter SQL extra en esa cadena cambia el filtro.
La consulta de abajo es la misma sentencia después de que alguien escribe un apellido que no cierra la comilla y añade `OR 1 = 1`. `1 = 1` es siempre verdadero, así que el WHERE ya no restringe filas. El mismo tipo de error en UPDATE o DELETE sin un WHERE estricto puede cambiar o borrar cada fila.
SELECT first_name, last_name FROM customers WHERE last_name = 'Lopez' OR 1 = 1 ORDER BY customer_id;
Resultado: Los ocho clientes. El filtro del nombre ya no limita el resultado.
La corrección: parámetros enlazados
No pegues texto de usuario en el SQL. Envía la sentencia con un marcador y pasa el valor aparte. PostgreSQL usa `$1`, `$2`, y así. La base trata el valor como datos, nunca como sintaxis, así que un apellido que parece SQL sigue siendo un apellido.
La consulta que escribes es entonces siempre `WHERE last_name = $1`. Las bibliotecas y los ORM lo llaman consulta parametrizada o prepared statement. Aun así hay que usarlo: un ORM que concatena cadenas tiene el mismo error.
SELECT first_name, last_name FROM customers WHERE last_name = 'Lopez' ORDER BY customer_id;
Resultado: Ana Lopez otra vez: la búsqueda con un valor enlazado, mostrada aquí con un literal porque este editor no tiene capa de aplicación.
Preguntas frecuentes
- ¿Basta con poner comillas de más alrededor del valor?
- No. Se olvida un escape, las codificaciones cambian y los números no van entre comillas. Los parámetros enlazados evitan toda esa clase de fallos.
- ¿Un ORM significa que puedo ignorar esto?
- Solo si cada consulta pasa por su API de parámetros. Las cadenas SQL crudas dentro de un ORM siguen siendo SQL concatenado. Prefiere el query builder o `execute(sql, [value])`.
- ¿Y UPDATE y DELETE?
- La misma regla: el WHERE debe usar parámetros, nunca texto pegado. Un WHERE ausente o roto en esas sentencias cambia una tabla entera de una vez.