1. ¿Qué es un ataque de inyección SQL?
El llamado ataque de inyección SQL significa que el atacante inserta comandos SQL en el campo de entrada de un formulario web o en la cadena de consulta de una solicitud de página, y engaña al servidor para que ejecute comandos SQL maliciosos. En algunas formas, la entrada del usuario se utiliza directamente para construir (o afectar) comandos SQL dinámicos, o como parámetros de entrada para procedimientos almacenados. Dichas formas son particularmente vulnerables a los ataques de inyección SQL. Los procesos comunes de ataque de inyección SQL incluyen:
⑴ Una aplicación web ASP.NET tiene una página de inicio de sesión. Esta página de inicio de sesión controla si el usuario tiene derecho a acceder a la aplicación. Requiere que el usuario ingrese un nombre y una contraseña.
⑵ El contenido ingresado en la página de inicio de sesión se usará directamente para construir comandos SQL dinámicos o se usará directamente como parámetros de procedimientos almacenados. A continuación se muestra un ejemplo de una aplicación ASP.NET que construye una consulta:
System.Text.StringBuilder query = new System.Text.StringBuilder(
"SELECCIONAR * de Usuarios DONDE iniciar sesión = '")
.Append(txtLogin.Text).Append("'Y contraseña='")
.Append(txtPassword.Text).Append("'");
⑶ El atacante ingresa algo como "' o '1'='1" en los cuadros de entrada de nombre de usuario y contraseña.
⑷ Después de enviar el contenido ingresado por el usuario al servidor, el servidor ejecuta el código ASP.NET anterior para construir un comando SQL para consultar al usuario. Sin embargo, debido a que el contenido ingresado por el atacante es muy especial, el comando SQL final. se convierte en: SELECCIONAR * de Usuarios DONDE inicio de sesión = '' o '1'='1' Y contraseña = '' o '1'='1'.
⑸ El servidor ejecuta una consulta o proceso almacenado para comparar la información de identidad ingresada por el usuario con la información de identidad guardada en el servidor.
⑹ Dado que el comando SQL en realidad ha sido modificado por el ataque de inyección y no puede autenticar realmente la identidad del usuario, el sistema autorizará incorrectamente al atacante.
Si un atacante sabe que la aplicación utilizará el contenido ingresado en el formulario directamente para consultas de verificación de identidad, intentará ingresar algunas cadenas SQL especiales para alterar la consulta y cambiar su funcionalidad original y engañar al sistema para que otorgue permisos de acceso.
Dependiendo del entorno del sistema, el daño que puede causar un atacante también es diferente, el cual viene determinado principalmente por los permisos de seguridad de la aplicación para acceder a la base de datos. Si la cuenta del usuario tiene derechos de administrador u otros derechos relativamente avanzados, el atacante puede realizar varias operaciones en las tablas de la base de datos que desee, incluida agregar, eliminar o actualizar datos, o incluso eliminar directamente la tabla.
2. ¿Cómo prevenir?
Afortunadamente, no es particularmente difícil evitar que las aplicaciones ASP.NET sean atacadas por ataques de inyección SQL. Todo lo que necesita hacer es filtrar todo el contenido de entrada antes de usar el contenido de entrada del formulario para construir el comando SQL. El filtrado de entradas se puede realizar de diversas formas.
⑴ Para situaciones en las que las consultas SQL se construyen dinámicamente, se pueden utilizar las siguientes técnicas:
Primero: reemplazar comillas simples, es decir, cambiar todas las comillas simples por dos comillas simples para evitar que los atacantes modifiquen el significado de los comandos SQL. Mirando nuevamente el ejemplo anterior, "SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'" obviamente obtendrá el mismo "SELECCIONAR * de Usuarios DONDE inicio de sesión = '' o '1'='1' Y contraseña = '' o '1'='1'" resultados diferentes.
Segundo: elimine todos los guiones en el contenido ingresado por el usuario para evitar que los atacantes creen consultas como "SELECT * from Users WHERE login = 'mas' -- AND contraseña =''", porque el sufijo de dichas consultas ha sido comentado. y ya no es válido. El atacante sólo necesita conocer un nombre de usuario legal y no necesita conocer la contraseña del usuario para obtener acceso exitosamente.
Tercero: limite los permisos de la cuenta de base de datos utilizada para ejecutar consultas. Utilice diferentes cuentas de usuario para realizar operaciones de consulta, inserción, actualización y eliminación. Al aislar las operaciones que pueden realizar diferentes cuentas, evita que el lugar utilizado originalmente para ejecutar el comando SELECT se utilice para ejecutar el comando INSERT, UPDATE o DELETE.
⑵ Utilice procedimientos almacenados para ejecutar todas las consultas. La forma en que se pasan los parámetros SQL evitará que los atacantes utilicen comillas simples y guiones para llevar a cabo ataques. Además, también permite restringir los permisos de la base de datos para permitir que solo se ejecuten procedimientos almacenados específicos. Todas las entradas del usuario deben cumplir con el contexto de seguridad del procedimiento almacenado llamado, por lo que es difícil que ocurran ataques de inyección.
⑶ Limite la longitud del formulario o la cadena de consulta ingresada. Si el nombre de inicio de sesión del usuario sólo tiene un máximo de 10 caracteres, no acepte más de 10 caracteres ingresados en el formulario. Esto aumentará en gran medida la dificultad para los atacantes de insertar código dañino en los comandos SQL.
⑷ Verifique la legalidad de la entrada del usuario y asegúrese de que el contenido de la entrada solo contenga datos legales. La inspección de datos debe realizarse tanto en el lado del cliente como en el del servidor; la validación del lado del servidor se realiza para compensar la frágil seguridad del mecanismo de validación del lado del cliente.
En el lado del cliente, es completamente posible que un atacante obtenga el código fuente de la página web, modifique el script que verifica la legalidad (o elimine el script directamente) y luego envíe el contenido ilegal al servidor a través del formulario modificado. Por lo tanto, la única forma de garantizar que la operación de verificación realmente se haya realizado es realizar la verificación también en el lado del servidor. Puede utilizar muchos de los objetos de validación integrados, como RegularExpressionValidator, que puede generar automáticamente scripts del lado del cliente para la validación y, por supuesto, también puede insertar llamadas a métodos del lado del servidor. Si no puede encontrar un objeto de validación listo para usar, puede crear uno usted mismo a través de CustomValidator.
⑸ Cifre y guarde el nombre de inicio de sesión del usuario, la contraseña y otros datos. Cifrar los datos ingresados por el usuario y luego compararlos con los datos guardados en la base de datos equivale a "esterilizar" los datos ingresados por el usuario. Los datos ingresados por el usuario ya no tienen ningún significado especial para la base de datos, por lo que evita. los atacantes inyecten comandos SQL. La clase System.Web.Security.FormsAuthentication tiene un HashPasswordForStoringInConfigFile, que es muy adecuado para desinfectar los datos de entrada.
⑹ Verifique la cantidad de registros devueltos por la consulta que extrajo los datos. Si el programa solo requiere que se devuelva un registro, pero el registro devuelto real tiene más de una fila, se tratará como un error.