¿Cómo prevenir la inyección SQL?
Defender con declaraciones preparadas y mínimo privilegio
Los artículos escritos en este blog fueron creados con el objetivo de enseñar. Además, la información del artículo puede ser incorrecta, así que tenga cuidado.
La inyección SQL no se evita eliminando todas las comillas de la entrada. Los comandos SQL y los datos del usuario deben separarse desde el principio para que los datos no se interpreten como comandos.
Utilice declaraciones preparadas
La declaración preparada o la consulta parametrizada marcan por separado el lugar donde se debe colocar el valor en la declaración SQL.
const sql = 'SELECT id, name, password_hash FROM users WHERE name = ?';
const [rows] = await database.execute(sql, [userName]);
if (rows.length === 1)
{
const passwordMatches = await passwordHasher.verify(
rows[0].password_hash,
password
);
}
aquí?El valor ingresado se transmite como datos, no como gramática SQL. Si el usuario utiliza comillas oORIncluso si ingresa la misma cadena, la estructura de la consulta no se puede cambiar.
Las contraseñas no se comparan entre textos sin formato en SQL. Después de obtener información del usuario como una consulta de parámetros, el valor de entrada se compara con un hash almacenado en una biblioteca de hash de contraseñas verificadas.
El uso de un ORM no hace que todo sea automáticamente más seguro. La misma vulnerabilidad ocurre si Raw Query se combina en una cadena sin utilizar la función de parámetro proporcionada por ORM.
Los nombres de las tablas y los criterios de clasificación se comparan con la lista de permitidos.
Los parámetros se utilizan generalmente para valores. nombre de la tabla, nombre de la columna,ASCa míDESCEn muchos casos, la misma posición de gramática SQL no se puede procesar como parámetro.
Estos valores no se pegan como la cadena del usuario, sino que se seleccionan de la lista de permitidos predeterminada por el servidor.
const allowedSortColumns = {
newest: 'created_at',
name: 'name'
};
const sortColumn = allowedSortColumns[requestedSort] ?? 'created_at';
const sql = `SELECT id, name FROM users ORDER BY ${sortColumn} DESC`;
requestedSortEs importante convertirlo en una cadena segura propiedad del servidor, en lugar de ponerlo en SQL.
Reducir los privilegios de la cuenta de base de datos
Si se otorgan privilegios de administrador a la cuenta de base de datos utilizada por el servidor web, el daño de una sola vulnerabilidad puede extenderse a toda la base de datos.
- Las funciones que solo realizan búsquedas reciben permiso de solo lectura.
- Accede sólo a las tablas que necesitas.
- No realice tareas de administración de bases de datos utilizando la cuenta de la aplicación web.
- Las contraseñas no se almacenan en texto plano, sino mediante un método hash verificado.
Los errores se registran en el servidor y se ocultan al usuario.
Si responde con un error SQL detallado tal cual, las estructuras internas, como los nombres de las tablas o los nombres de las columnas, pueden quedar expuestas. Se debe mostrar al usuario un mensaje de error general y los errores detallados se deben registrar en un registro del servidor con acceso controlado.
Las herramientas de validación de entradas, firewall y detección también pueden ayudar. Pero lo primero que debe hacer es parametrizar todas las consultas, limitar la sintaxis SQL ingresada dinámicamente a una lista blanca y minimizar los permisos de la base de datos.