Diferencia entre revisiones de «SQL»
(Creacion del apartado SQL) |
Sin resumen de edición |
||
| (No se muestran 3 ediciones intermedias 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. | |||
== 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 == | == Conceptos Fundamentales == | ||
| Línea 9: | Línea 35: | ||
* ''Registro (Row)'' — Una entrada individual dentro de una tabla. | * ''Registro (Row)'' — Una entrada individual dentro de una tabla. | ||
* ''Campo (Field)'' — Un atributo específico 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:<pre style="color: blue"> | Ejemplo de creación de tabla:<pre style="color: blue"> | ||
| Línea 18: | Línea 48: | ||
); | ); | ||
</pre> | </pre> | ||
== 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 == | == Consultas SQL Básicas == | ||
| Línea 49: | Línea 88: | ||
DELETE FROM usuarios WHERE id = 3; | DELETE FROM usuarios WHERE id = 3; | ||
</pre> | </pre> | ||
== 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 == | == Seguridad y Buenas Prácticas == | ||
* '''Validación de entradas:''' Evita la inyección SQL usando consultas preparadas. | * '''Validación de entradas:''' Evita la inyección SQL usando consultas preparadas y validación estricta de tipos y longitudes. | ||
* '''Principio de menor privilegio:''' | * '''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:''' | * '''Cifrado:''' Almacenar contraseñas usando hash con sal (por ejemplo, bcrypt o Argon2). No almacenar contraseñas en texto plano. | ||
* '''Auditoría:''' | * '''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 | === Ejemplo representativo === | ||
<pre style="color: red"> | |||
' OR '1'='1 | ' OR '1'='1 | ||
</pre> | </pre> | ||
*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): | |||
<pre style="color: blue"> | |||
$stmt = $pdo->prepare('SELECT * FROM usuarios WHERE correo = ? AND contraseña = ?'); | |||
$stmt->execute([$correo, $hash]); | |||
$result = $stmt->fetch(); | |||
</pre> | |||
Ejemplo en Python (psycopg2): | |||
<pre style="color: blue"> | |||
cur.execute("SELECT * FROM usuarios WHERE correo = %s AND contraseña = %s", (correo, hash)) | |||
</pre>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): | |||
<pre style="color: red"> | |||
$sql = "SELECT * FROM usuarios WHERE correo = '" . $_POST['correo'] . "' AND contraseña = '" . $_POST['pass'] . "'"; | |||
</pre> | |||
*Corrección con prepared statement (recomendada): | |||
<pre style="color: blue"> | |||
$stmt = $pdo->prepare("SELECT * FROM usuarios WHERE correo = :correo AND contraseña = :pass"); | |||
$stmt->bindParam(':correo', $_POST['correo']); | |||
$stmt->bindParam(':pass', $hash); | |||
$stmt->execute(); | |||
</pre> | |||
=== 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. | |||
== 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.