5.- Inyección SQL con ejemplos de diferentes tipos.

--

La inyección SQL (SQLi) es un tipo de vulnerabilidad en la cual el atacante accede a información privada mediante consultas SQL en el campo de entrada del usuario que modifican la ejecución de comandos SQL.
Has aprendido que existen cuatro tipos de inyecciones SQL:
* Manipulación SQL
* Inyección de código
* Inyección de llamada a funciones
* Desbordamientos de búfer

En este laboratorio, nos centraremos en la manipulación SQL, que es común en aplicaciones web.
Para este laboratorio, necesitaremos:
• Bandit (escáner de vulnerabilidades para archivos Python)
• Paquete de Python (archivos de prueba para el escaneo)

Instalación de Bandit
Bandit es una herramienta de prueba de seguridad de aplicaciones estáticas de código abierto (SAST) que puede escanear vulnerabilidades en aplicaciones web escritas en Python.

pip install bandit
wget https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBM-CD0267EN-SkillsNetwork/labs/module3/web_app_example.py
bandit -r web_app_example.py

Examinar el SQL injection:

Ocurre según nos dice en la linea 16

En la línea anterior, las entradas del usuario para el nombre de usuario y la contraseña fueron concatenadas en la consulta SQL. Como resultado, un atacante podría ingresar una entrada de nombre de usuario como:

' OR 1=1; - .

Esto resulta en la siguiente cadena de consulta SQL:

SELECT * FROM users WHERE username = ‘’ OR 1=1; — ‘ AND password = ‘%s’

¿Qué implica esta consulta SQL? Examinemos cada parte por separado:

- La primera parte “SELECT * FROM users WHERE username = ‘’” representa una consulta completa que devuelve cualquier registro en la base de datos con “username=’’” (nombre de usuario vacío). Esta es una consulta válida que no devolverá nada siempre y cuando no haya nombres de usuario vacíos.
- Sin embargo, la condición “OR 1=1” que le sigue siempre se evaluará como VERDADERO, por lo que la consulta devolverá todos los usuarios en la tabla.
- El “;” marca el final de una consulta y el “-” después de él comentará el resto de la cadena de consulta. En última instancia, la entrada de la contraseña ni siquiera importaría.

Este no es el único modo en que un atacante puede hackear el sistema. Usando la misma lógica, uno también podría incluir consultas SQL adicionales para eliminar toda la base de datos con DROP, o obtener acceso de administrador con UPDATE y SET siempre y cuando comenten las partes no deseadas de la cadena de consulta original.

Mitigar la Vulnerabilidad:

Para prevenir estos problemas, necesitarás modificar el código para usar parámetros de sustitución.

Los parámetros de sustitución te permiten poner marcadores de posición en el código que serán reemplazados por las variables que pasas al intérprete de SQL. Es importante tener en cuenta que los parámetros de sustitución pueden ser diferentes para otras variantes de SQL. Consulta la documentación de la versión de SQL que estás utilizando. En este caso, estamos usando “%s” como marcador de posición para una cadena que se sustituirá en tiempo de ejecución.

Actualicemos el archivo “web_app_example.py” con esta línea de código reemplazando las líneas 16 y 17 con las líneas anteriores.

Cambios en el código con la inyección:

Cambia la consulta SQL en las líneas 16 y 17 en el código Python. No utilices la concatenación de cadenas y usa marcadores de sustitución (“%s”) en su lugar:

sql = “SELECT * FROM users WHERE username = %s AND password = %s”
cursor.execute(sql, (username, password))

Al eliminar la concatenación de cadenas para el nombre de usuario y la contraseña, le estás indicando al motor de SQL que las interprete como una cadena y no como un comando. Esto elimina la posibilidad de inyección de comandos SQL.
Observa que también llamamos a una forma diferente de cursor.execute(), donde toma dos parámetros: la cadena SQL y una tupla de variables que se utilizarán con los marcadores de posición %s como parámetros de sustitución.

Comprobar cambio de nuevo con bandit:

bandit -r web_app_example.py

Prevenir Ataques de Inyección SQL

Aquí hay algunas recomendaciones para prevenir ataques de Inyección SQL al programar:

• Sentencias preparadas con consultas parametrizadas: este enfoque para escribir código SQL obliga a los desarrolladores a pasar parámetros por separado a la consulta, lo que evitará que los atacantes se aprovechen de la sintaxis SQL.

• Verificar dos veces los paquetes importados: PyPi es una gran fuente para paquetes seguros, pero no todos están verificados. Si un paquete no es muy conocido, es bueno investigar si es confiable o no.

• Hacer una lista de posibles vulnerabilidades: esto te ayudará a estar atento mientras programas.

  • Escanear tu aplicación: además de herramientas de prueba de seguridad estática de aplicaciones como Bandit, también puedes utilizar herramientas de prueba de seguridad dinámica de aplicaciones que escanearán la aplicación web utilizando su URL mientras está en ejecución.

Segunda Parte: Tests de Seguridad y Estrategias de Mitigación

Lab 1: Usando Análisis Estático
Lab 2: Usando Análisis Dinámico
Lab 3: Evaluando el Análisis de Vulnerabilidades
Lab 4: Evaluando “Software Component Analysis (SCA)”

Tercera Parte: OWASP Top 10 vulnerabilidades

Lab 5: Comprendiendo SQL Injections
Lab 6: Cross Site Scripting XSS
Lab 7: Guardando Secretos de forma Segura

Cuarta Parte: Mejores Prácticas

Lab 8: Code Practices
Lab 9: Secure Development Environment

--

--

Fernando Muinos
Cibersecurity, Malware and Secure Development

Founder Hubots.ai. Innovative startup dedicated to providing advanced applications and services that help companies increase their productivity by AGI.