Diferencia entre revisiones de «SQL»
Sin resumen de edición |
Sin resumen de edición |
||
| (No se muestra una edición intermedia del mismo usuario) | |||
| Línea 1: | Línea 1: | ||
'''SQL''' (Structured Query Language) es el lenguaje estándar utilizado para gestionar y manipular bases de datos relacionales. En el ámbito de la '''ciberseguridad''', comprender SQL es fundamental para identificar vulnerabilidades, prevenir inyecciones maliciosas y asegurar la integridad de los datos. | '''SQL''' (Structured Query Language) es el lenguaje estándar utilizado para gestionar y manipular bases de datos relacionales. En el ámbito de la '''ciberseguridad''', comprender SQL es fundamental para identificar vulnerabilidades, prevenir inyecciones maliciosas y asegurar la integridad de los datos. | ||
| Línea 118: | Línea 117: | ||
' OR '1'='1 | ' OR '1'='1 | ||
</pre> | </pre> | ||
*Si | *Si esta cadena se concatena en una consulta de autenticación sin protección, la condición lógica puede resultar siempre verdadera y permitir acceso no autorizado. Este ejemplo se usa para ilustrar el concepto; la exposición real siempre depende del contexto de la consulta y del tratamiento que haga la aplicación de la entrada. | ||
=== Tipos comunes de inyección (visión general) === | === Tipos comunes de inyección (visión general) === | ||
| Línea 144: | Línea 143: | ||
=== Prevención y mitigación (prácticas recomendadas) === | === Prevención y mitigación (prácticas recomendadas) === | ||
1. Mantener separación entre código y datos | |||
* '''Consultas preparadas / parámetros enlazados''' (prepared statements): la forma más efectiva de evitar que la entrada del usuario sea interpretada como código SQL. | * '''Consultas preparadas / parámetros enlazados''' (prepared statements): la forma más efectiva de evitar que la entrada del usuario sea interpretada como código SQL. | ||
Ejemplo en PHP (PDO): | Ejemplo en PHP (PDO): | ||
| Línea 157: | Línea 155: | ||
<pre style="color: blue"> | <pre style="color: blue"> | ||
cur.execute("SELECT * FROM usuarios WHERE correo = %s AND contraseña = %s", (correo, hash)) | cur.execute("SELECT * FROM usuarios WHERE correo = %s AND contraseña = %s", (correo, hash)) | ||
</pre> | </pre>2. Validación y saneamiento | ||
* Validar tipo, longitud, formato (ej. emails, números, fechas) antes de procesar. | * Validar tipo, longitud, formato (ej. emails, números, fechas) antes de procesar. | ||
* Rechazar o normalizar entradas inesperadas. | * Rechazar o normalizar entradas inesperadas. | ||
* Evitar la construcción dinámica de SQL con concatenación de strings. | * Evitar la construcción dinámica de SQL con concatenación de strings. | ||
3. Principio de menor privilegio | |||
* La cuenta que usa la aplicación para conectarse debe tener permisos mínimos (por ejemplo SELECT/INSERT/UPDATE en tablas necesarias, sin DROP ni DDL excesivo). | * La cuenta que usa la aplicación para conectarse debe tener permisos mínimos (por ejemplo SELECT/INSERT/UPDATE en tablas necesarias, sin DROP ni DDL excesivo). | ||
4. Uso de ORMs con cuidado | |||
* Los ORMs suelen parametrizar consultas correctamente, pero el uso de consultas «raw» o concatenadas puede introducir riesgos. Revisar y auditar el código que construye SQL manualmente. | * Los ORMs suelen parametrizar consultas correctamente, pero el uso de consultas «raw» o concatenadas puede introducir riesgos. Revisar y auditar el código que construye SQL manualmente. | ||
5. Manejo seguro de errores y mensajes | |||
* No mostrar trazas o errores SQL al usuario. Registrar internamente la información suficiente para investigar sin exponer estructura ni datos. | * No mostrar trazas o errores SQL al usuario. Registrar internamente la información suficiente para investigar sin exponer estructura ni datos. | ||
6. Registro, monitoreo y respuesta | |||
* Implementar alertas ante patrones sospechosos (picos de errores, inputs raros). | * Implementar alertas ante patrones sospechosos (picos de errores, inputs raros). | ||
* Mantener logs de consultas y accesos para análisis forense. | * Mantener logs de consultas y accesos para análisis forense. | ||
7. Controles adicionales | |||
* Web Application Firewall (WAF) como capa adicional — útil pero no sustituye buenas prácticas de codificación. | * Web Application Firewall (WAF) como capa adicional — útil pero no sustituye buenas prácticas de codificación. | ||
* Hardening y parches de la BD y del servidor de aplicaciones. | * Hardening y parches de la BD y del servidor de aplicaciones. | ||
| Línea 184: | Línea 185: | ||
=== Ejemplos de corrección (antes / después) === | === Ejemplos de corrección (antes / después) === | ||
*Código vulnerable (no usar): | *Código vulnerable (no usar): | ||
<pre style="color: red"> | <pre style="color: red"> | ||
$sql = "SELECT * FROM usuarios WHERE correo = '" . $_POST['correo'] . "' AND contraseña = '" . $_POST['pass'] . "'"; | $sql = "SELECT * FROM usuarios WHERE correo = '" . $_POST['correo'] . "' AND contraseña = '" . $_POST['pass'] . "'"; | ||
</pre> | </pre> | ||
*Corrección con prepared statement (recomendada): | *Corrección con prepared statement (recomendada): | ||
<pre style="color: blue"> | <pre style="color: blue"> | ||
$stmt = $pdo->prepare("SELECT * FROM usuarios WHERE correo = :correo AND contraseña = :pass"); | $stmt = $pdo->prepare("SELECT * FROM usuarios WHERE correo = :correo AND contraseña = :pass"); | ||
| Línea 199: | Línea 200: | ||
=== Respuesta ante un incidente === | === Respuesta ante un incidente === | ||
1. Contener: desactivar vectores afectados (ej. endpoints vulnerables), cambiar credenciales si fuera necesario. | 1. Contener: desactivar vectores afectados (ej. endpoints vulnerables), cambiar credenciales si fuera necesario. | ||
2. Analizar logs para identificar alcance y vectores. | 2. Analizar logs para identificar alcance y vectores. | ||
3. Restaurar desde backups conocidas si hay pérdida o corrupción de datos. | 3. Restaurar desde backups conocidas si hay pérdida o corrupción de datos. | ||
4. Corregir la vulnerabilidad (parche, refactorización de consultas) y ejecutar pruebas. | 4. Corregir la vulnerabilidad (parche, refactorización de consultas) y ejecutar pruebas. | ||
5. Notificar a las partes afectadas según normativa/Política de divulgación y cumplimiento legal. | 5. Notificar a las partes afectadas según normativa/Política de divulgación y cumplimiento legal. | ||
| Línea 212: | Línea 217: | ||
* Revisar siempre los puntos del código que generan SQL dinámico y tratarlos como zonas críticas de seguridad. | * Revisar siempre los puntos del código que generan SQL dinámico y tratarlos como zonas críticas de seguridad. | ||
[[ | == Bibliografía == | ||
[https://pedrobeltrancanessa-biblioteca.weebly.com/uploads/1/2/4/0/12405072/fundamentos_de_sql_3edi_oppel.pdf Fundamentos de SQL - Andy Oppel Robert Sheldon] | |||
[https://es.wikipedia.org/wiki/MySQL MySQL - Wikipedia] | |||
[[Categoría:Bases de datos]] | |||
Revisión actual - 21:03 28 oct 2025
SQL (Structured Query Language) es el lenguaje estándar utilizado para gestionar y manipular bases de datos relacionales. En el ámbito de la ciberseguridad, comprender SQL es fundamental para identificar vulnerabilidades, prevenir inyecciones maliciosas y asegurar la integridad de los datos.
Características
1. Jerárquico:
- Estructura tipo árbol invertido (nodos primarios y secundarios).
- Un nodo principal puede tener muchos secundarios, pero un nodo secundario solo un principal.
- Datos organizados en nodos, equivalente lógico a tablas.
- Limitaciones: inflexible, difícil manejar relaciones complejas.
Ejemplo: IMS de IBM, que añade características para superar limitaciones.
2. Red:
- Mejora las limitaciones del modelo jerárquico.
- Datos organizados en tipos de registro, equivalente lógico a tablas.
- Relaciona pares de registros como propietarios y miembros, permitiendo relaciones más complejas.
Limitaciones: complejidad, requiere que el usuario conozca la estructura, difícil modificar sin afectar aplicaciones
3. Relacional:
- Basado en tablas (relaciones) y relaciones entre ellas.
- Independiente de la aplicación: cambios en la estructura no afectan la aplicación.
- Permite definir relaciones complejas sin necesidad de navegar por estructuras jerárquicas o de red.
- Ventaja: acceso directo a cada tabla sin las limitaciones de jerarquía o propietario/miembro.
- Mejora la flexibilidad y mantenibilidad respecto a jerárquico y en red.
Conceptos Fundamentales
- Base de datos (Database) — Colección organizada de información.
- Tabla (Table) — Estructura que almacena los datos en filas y columnas.
- Registro (Row) — Una entrada individual dentro de una tabla.
- Campo (Field) — Un atributo específico dentro de una tabla.
- Clave primaria (Primary Key) — Identificador único de cada registro.
- Índice (Index) — Estructura que acelera búsquedas sobre columnas.
- Normalización — Proceso de diseñar tablas para reducir redundancia y mejorar integridad.
- Transacción — Conjunto de operaciones que se ejecutan de forma atómica (ACID).
Ejemplo de creación de tabla:
CREATE TABLE usuarios (
id INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(50),
correo VARCHAR(100),
contraseña VARCHAR(100)
);
Estructura y Diseño
- Normalización: aplicar formas normales (1FN, 2FN, 3FN...) para evitar datos redundantes y anomalías de actualización.
- Desnormalización: a veces usada por motivos de rendimiento en consultas analíticas o sistemas OLAP.
- Constraints (Restricciones): NOT NULL, UNIQUE, CHECK, FOREIGN KEY para mantener la integridad referencial.
- Índices: deben diseñarse con cuidado; ayudan a acelerar SELECT pero pueden ralentizar INSERT/UPDATE/DELETE.
- Particionamiento y Sharding: técnicas para distribuir datos en varias unidades físicas para escalabilidad.
- Backups y recuperación: estrategias (completos, incrementales, logs de transacción) y pruebas periódicas de restauración.
Consultas SQL Básicas
- SELECT
- Utilizado para consultar información dentro de una base de datos.
SELECT * FROM usuarios;
- INSERT
- Añade nuevos registros a una tabla.
INSERT INTO usuarios (nombre, correo, contraseña)
VALUES ('user', 'user@darfe.es', 'clave123');
- UPDATE
- Modifica registros existentes.
UPDATE usuarios SET contraseña = 'claveNueva' WHERE nombre = 'Darfe';
- DELETE
- Elimina registros de una tabla.
DELETE FROM usuarios WHERE id = 3;
Operaciones Avanzadas
- JOINs: INNER JOIN, LEFT/RIGHT JOIN, FULL OUTER JOIN para combinar datos de varias tablas.
- Subconsultas: consultas dentro de otras consultas para operaciones complejas.
- Funciones de agregación: COUNT(), SUM(), AVG(), MIN(), MAX() y GROUP BY para resúmenes.
- Views (Vistas): consultas guardadas que simplifican acceso y encapsulan lógica.
- Stored Procedures y Triggers: lógica almacenada en la BD — cuidado con la complejidad y permisos.
- Optimización de consultas: EXPLAIN/EXPLAIN ANALYZE para revisar planes de ejecución y refinar índices.
Seguridad y Buenas Prácticas
- Validación de entradas: Evita la inyección SQL usando consultas preparadas y validación estricta de tipos y longitudes.
- Principio de menor privilegio: Las cuentas que acceden a la BD deben tener solo los permisos necesarios (no usar root/sa en la app).
- Cifrado: Almacenar contraseñas usando hash con sal (por ejemplo, bcrypt o Argon2). No almacenar contraseñas en texto plano.
- Auditoría y logging: Monitorear accesos, cambios en esquemas y operaciones en tablas sensibles.
- Configuración segura: Deshabilitar funciones innecesarias, aplicar parches y mantener la BD actualizada.
- Seguridad de red: Aislar la infraestructura de BD en segmentos privados, usar TLS/SSL para conexiones y VPNs cuando corresponda.
- Pruebas regulares: Integrar escaneos de seguridad y pruebas de penetración en el ciclo de desarrollo.
Inyección SQL (tema desarrollado)
Definición
La inyección SQL (SQL Injection) es una vulnerabilidad que permite a un atacante insertar, manipular o alterar consultas SQL construidas dinámicamente por una aplicación. Sucede cuando datos controlados por el usuario se incorporan directamente en una consulta sin separación clara entre código y datos.
Ejemplo representativo
' OR '1'='1
- Si esta cadena se concatena en una consulta de autenticación sin protección, la condición lógica puede resultar siempre verdadera y permitir acceso no autorizado. Este ejemplo se usa para ilustrar el concepto; la exposición real siempre depende del contexto de la consulta y del tratamiento que haga la aplicación de la entrada.
Tipos comunes de inyección (visión general)
- Basada en errores (Error-based): El atacante provoca errores que pueden revelar información sobre la estructura de la BD.
- Basada en booleanos (Boolean-based / Blind): El atacante envía consultas que devuelven true/false y deduce información a partir de la respuesta de la aplicación.
- Basada en tiempo (Time-based / Blind): Se inyectan operaciones que tardan en ejecutarse para inferir datos según la latencia observada.
- UNION-based: Combinar resultados de consultas adicionales usando UNION para extraer datos.
- Stacked queries (consultas apiladas): Ejecutar múltiples sentencias en una sola petición (no soportado por todas las BD o APIs).
> Nota: aquí no se proporcionan payloads avanzados ni instrucciones para explotar sistemas — el objetivo es entender los vectores para diseñar defensas efectivas.
Indicadores y detección
- Comportamiento inesperado en formularios (logins, búsquedas).
- Mensajes de error SQL reveladores en la interfaz (evitar mostrarlos a usuarios).
- Respuestas distintas al introducir caracteres especiales (' " ; -- /*).
- Auditoría que muestra consultas construidas dinámicamente con concatenación de inputs.
- Pruebas automatizadas y herramientas de escaneo (SAST/DAST) que señalan puntos de inyección.
Consecuencias potenciales
- Acceso no autorizado a datos sensibles (usuarios, contraseñas, registros financieros).
- Exfiltración masiva de datos.
- Alteración o borrado de información crítica.
- Escalada de privilegios o ejecución de código si la BD o entorno lo permite.
- Compromiso del sistema completo si la aplicación y la BD están integradas sin separación.
Prevención y mitigación (prácticas recomendadas)
1. Mantener separación entre código y datos
- Consultas preparadas / parámetros enlazados (prepared statements): la forma más efectiva de evitar que la entrada del usuario sea interpretada como código SQL.
Ejemplo en PHP (PDO):
$stmt = $pdo->prepare('SELECT * FROM usuarios WHERE correo = ? AND contraseña = ?');
$stmt->execute([$correo, $hash]);
$result = $stmt->fetch();
Ejemplo en Python (psycopg2):
cur.execute("SELECT * FROM usuarios WHERE correo = %s AND contraseña = %s", (correo, hash))
2. Validación y saneamiento
- Validar tipo, longitud, formato (ej. emails, números, fechas) antes de procesar.
- Rechazar o normalizar entradas inesperadas.
- Evitar la construcción dinámica de SQL con concatenación de strings.
3. Principio de menor privilegio
- La cuenta que usa la aplicación para conectarse debe tener permisos mínimos (por ejemplo SELECT/INSERT/UPDATE en tablas necesarias, sin DROP ni DDL excesivo).
4. Uso de ORMs con cuidado
- Los ORMs suelen parametrizar consultas correctamente, pero el uso de consultas «raw» o concatenadas puede introducir riesgos. Revisar y auditar el código que construye SQL manualmente.
5. Manejo seguro de errores y mensajes
- No mostrar trazas o errores SQL al usuario. Registrar internamente la información suficiente para investigar sin exponer estructura ni datos.
6. Registro, monitoreo y respuesta
- Implementar alertas ante patrones sospechosos (picos de errores, inputs raros).
- Mantener logs de consultas y accesos para análisis forense.
7. Controles adicionales
- Web Application Firewall (WAF) como capa adicional — útil pero no sustituye buenas prácticas de codificación.
- Hardening y parches de la BD y del servidor de aplicaciones.
- Revisión de código y pruebas de seguridad (pentests, fuzzing) periódicas.
Ejemplos de corrección (antes / después)
- Código vulnerable (no usar):
$sql = "SELECT * FROM usuarios WHERE correo = '" . $_POST['correo'] . "' AND contraseña = '" . $_POST['pass'] . "'";
- Corrección con prepared statement (recomendada):
$stmt = $pdo->prepare("SELECT * FROM usuarios WHERE correo = :correo AND contraseña = :pass");
$stmt->bindParam(':correo', $_POST['correo']);
$stmt->bindParam(':pass', $hash);
$stmt->execute();
Respuesta ante un incidente
1. Contener: desactivar vectores afectados (ej. endpoints vulnerables), cambiar credenciales si fuera necesario.
2. Analizar logs para identificar alcance y vectores.
3. Restaurar desde backups conocidas si hay pérdida o corrupción de datos.
4. Corregir la vulnerabilidad (parche, refactorización de consultas) y ejecutar pruebas.
5. Notificar a las partes afectadas según normativa/Política de divulgación y cumplimiento legal.
Recursos y pruebas seguras
- Usar entornos de laboratorio aislados (no en producción) para practicar detección/mitigación.
- Emplear herramientas de seguridad para evaluar de forma controlada (sólo en sistemas de prueba o con autorización explícita).
Referencias rápidas
- Aprender SQL es clave para desarrollar con seguridad: entender cómo se construyen consultas permite tanto optimizar rendimiento como prevenir fallos de seguridad.
- Revisar siempre los puntos del código que generan SQL dinámico y tratarlos como zonas críticas de seguridad.