Saltar al contenido

lección 5

Día 3 (tarde) -- El incidente de acceso no autorizado

Diego accedió a datos de pacientes sin autorización. El audit trail que acabas de implementar lo detecta. Gestión del incidente en tiempo real: contención, investigación, documentación y decisión sobre notificación a la AEPD.

⏱ 55 min

## Miércoles, 14:34 UTC (16:34 en Valencia) -- La alerta

Dataset de esta lección (en tu carpeta datos/): datos/access_log_sample.json (JSON Lines). Para la investigación forense del incidente de diego.ferrer te apoyarás en los campos user, timestamp, table, operation, query, rows_returned y source_ip de cada acceso, reconstruyendo la cronología de lo que hizo Diego. Es el mismo fichero de accesos del audit trail que preparaste por la mañana.

Estás terminando de desplegar los triggers de auditoría cuando tu correo recibe una alerta automática del sistema de detección de anomalías (que Laura configuró hace meses para queries sospechosas). El asunto dice: "ALERTA: acceso masivo a datos de pacientes - usuario diego.ferrer". Te quedas frío: diego.ferrer es Diego, tu compañero.

1DE: alertas-seguridad@meditrack.es
2PARA: laura.sanchez@meditrack.es, tu@meditrack.es
3CC: rosa.martinez@meditrack.es
4ASUNTO: [ALERTA SEGURIDAD] Acceso anómalo detectado
5
6Timestamp: 2024-09-18 14:32:15 UTC
7Usuario: diego.ferrer (Diego Ferrer, Junior Data Engineer)
8Aplicación: psql (cliente SQL directo, no la aplicación)
9Sesión: sess_diego_anomalo
10
11Actividad detectada (UNA sola consulta, 4.521 ms):
12- SELECT p.*, d.codigo_cie10, d.descripcion
13 FROM pacientes p JOIN diagnosticos d ON d.paciente_id = p.id
14 WHERE d.es_cronico = true
15- 12.847 registros devueltos, sin LIMIT
16- Cruza identidad (p.*: nombre, DNI, email, teléfono, dirección)
17 con diagnósticos crónicos (CIE-10 + descripción)
18- IP: 10.0.1.45 (red interna)
19
20Contexto:
21diego.ferrer consulta a diario muestras pequeñas de las tablas para
22depurar pipelines: siempre con LIMIT, nunca más de 500 filas, nunca
23un JOIN entre pacientes y diagnosticos, y siempre por la mañana.
24Este acceso se sale de las tres cosas a la vez.
25
26ACCIÓN REQUERIDA: Verificar legitimidad del acceso.

El audit trail FUNCIONA -- acaba de detectar algo que no deberia pasar

Laura aparece en tu puesto en 30 segundos. "Has visto el email?" Asientes. Laura cierra la puerta de la sala: "Diego ha sacado de golpe 12.847 registros de pacientes con sus diagnósticos crónicos. No tiene ninguna tarea asignada que justifique ese cruce. Esto es un incidente de seguridad. Tenemos que actuar ahora."

Sientes un nudo en el estómago. Diego es TU compañero. Le mentorizas. Es un chaval de 24 años que probablemente no sabía lo que estaba haciendo. Pero eso no cambia el hecho: ha accedido a datos de categoría especial sin consentimiento, sin finalidad declarada y sin ninguna tarea que lo justifique. En términos legales, es una brecha de confidencialidad interna.

## Fase 1: Contención inmediata

Laura toma el mando: "Primero contenemos. Después investigamos. No acuses a nadie hasta que sepamos qué pasó." Las acciones inmediatas:

  1. 01.Revocar acceso de Diego a tablas de pacientes e historiales (inmediato, sin explicación todavía)
  2. 02.Verificar si los datos fueron exportados fuera del sistema (downloads, copias, envíos por email)
  3. 03.Preservar evidencia: snapshot del audit trail con las queries exactas de Diego
  4. 04.Notificar a Rosa (DPO) -- ella decide si hay obligación de notificar a la AEPD en 72h
  5. 05.No confrontar a Diego todavía -- Rosa quiere hablar con él primero junto con RRHH
1Laura Sánchez 14:41 UTC DM a ti
2No le digas nada a Diego todavía. Sé que es tu compañero y esto
3es incómodo. Pero Rosa tiene que evaluar la gravedad primero.
4
5Necesito que hagas:
61. Query al audit trail: TODO lo que hizo Diego hoy
72. Verificar si hizo COPY TO o pg_dump (exportación)
83. Comprobar si envió algo por email o Slack (esto lo hace IT)
94. Documentar la cronología exacta
10
11Yo voy a revocarle acceso ahora. Si te pregunta, dile que hay
12un "mantenimiento de permisos" y que es temporal.
13
14Rosa Martínez 14:44 UTC DM a Laura
15Laura, necesito un informe del incidente en mi mesa antes de las 18h.
16Tengo 72 horas para decidir si notificamos a la AEPD (Art. 33).
17Si los datos NO salieron del sistema, puede que no sea obligatorio.
18Pero necesito estar SEGURA.

La tensión es real -- tu compañero puede estar en problemas serios

## Fase 2: Investigación

Tu rol ahora es técnico: investigar qué hizo Diego exactamente. Sin juicio, sin emoción. Los hechos primero. Ejecutas una serie de queries contra el audit trail para reconstruir la cronología:

1-- Investigacion: reconstruir TODA la actividad de diego.ferrer el día del incidente
2SELECT timestamp_utc, operacion, tabla_afectada, num_registros,
3 duration_ms, aplicacion, ip_origen, query_ejecutada
4FROM audit_accesos_pacientes
5WHERE usuario_id = 'diego.ferrer'
6 AND CAST(timestamp_utc AS DATE) = DATE '2024-09-18'
7ORDER BY timestamp_utc;
8
9-- Resultado (una sola fila):
10-- 14:32:15 SELECT pacientes 12847 4521 ms psql 10.0.1.45
11-- "SELECT p.*, d.codigo_cie10, d.descripcion FROM pacientes p
12-- JOIN diagnosticos d ON d.paciente_id = p.id WHERE d.es_cronico = true"
13
14-- Y su linea base: como trabaja Diego el resto del log
15SELECT COUNT(*) AS accesos,
16 MIN(EXTRACT(HOUR FROM timestamp_utc)) AS hora_min,
17 MAX(EXTRACT(HOUR FROM timestamp_utc)) AS hora_max,
18 MAX(num_registros) AS max_filas,
19 MEDIAN(num_registros) AS mediana_filas,
20 SUM(CASE WHEN query_ejecutada ILIKE '%JOIN%' THEN 1 ELSE 0 END) AS con_join
21FROM audit_accesos_pacientes
22WHERE usuario_id = 'diego.ferrer'
23 AND CAST(timestamp_utc AS DATE) <> DATE '2024-09-18';
24
25-- Resultado:
26-- accesos 1771 | hora 8-8 UTC | max_filas 500 | mediana 100 | con_join 0

El audit trail muestra la cronología exacta -- de lo legítimo a lo no autorizado

El patrón es claro: Diego trabaja siempre por la mañana, con muestras pequeñas y con LIMIT, y nunca cruza tablas. El 18 de septiembre a las 14:32 UTC lanza una sola consulta sin LIMIT que une pacientes (nombre, DNI, email, teléfono, dirección) con sus diagnósticos crónicos. Sin finalidad, sin justificación, desde psql. Tuvo en pantalla la identidad de miles de personas junto a sus enfermedades crónicas.

## La conversación con Diego (después)

Rosa habla con Diego al día siguiente junto con RRHH y Laura. Tú no estás en esa reunión, pero Laura te cuenta después. La versión de Diego:

1Laura Sánchez (jueves mañana, después de la reunión con Diego)
2
3"Te cuento lo que pasó. Diego dice que el Dr. Martín le pidió
4directamente -- sin pasar por nosotros -- que le sacara 'unos datos
5rápidos' sobre pacientes crónicos (diabetes, hipertensión...) para
6una presentación interna. Diego, queriendo agradar, lo hizo sin
7preguntar si tenía permiso.
8
9Rosa está furiosa -- no con Diego (que es junior y no sabía),
10sino con el protocolo que permitía que esto pasara. Un junior
11NO debería tener acceso a esas tablas en primer lugar.
12
13Consecuencias:
14- Diego: amonestación verbal + formación obligatoria en GDPR
15- Dr. Martín: Rosa va a tener una 'conversación seria' con él
16- Nosotros: implementar RLS para que esto SEA IMPOSIBLE técnicamente
17- Nadie ha sido despedido -- fue un error de ignorancia, no malicia
18
19Lo que ayuda: los datos NO salieron del sistema. Diego no
20copió nada, no envió nada. Lanzó una SELECT desde psql y miró
21los resultados en pantalla. Eso REDUCE el riesgo, pero no lo
22elimina: acceder sin autorización a datos de salud ya es una
23violación (Art. 4.12), aunque el dato no salga. Así que la
24pregunta del Art. 33 no es 'salieron o no' sino 'es improbable
25que haya riesgo'. Rosa se inclina por NOTIFICAR y documentarlo:
26con 12.847 registros de diagnósticos de por medio, prefiere pecar
27de prudente. La decisión la toma ella por escrito, argumentando
28el riesgo -- no la damos por hecha nosotros."
29
30Tú: "Pobre Diego. Pero entiendo -- tiene que aprender que no
31puedes sacar datos de salud porque alguien te lo pide
32informalmente."
33
34Laura: "Exacto. Y por eso necesitamos RLS implementado MAÑANA.
35Que sea técnicamente imposible repetir esto."

No hubo malicia -- pero eso no cambia que sea un incidente de seguridad

Consejo de senior: Los incidentes de seguridad más comunes no son hackers externos -- son empleados internos que cometen errores por desconocimiento. El 80% de las brechas de datos son internas. La solución no es castigar (Diego no tenía mala intención) sino hacer que sea TECNICAMENTE IMPOSIBLE repetir el error. Eso es Row-Level Security: no depender de que la gente "se acuerde" de no acceder a datos -- hacer que el sistema IMPIDA el acceso aunque lo intenten.

Cuidado con el atajo mental "sin exfiltración no hay riesgo": es jurídicamente falso y es el error más caro de esta lección. El Art. 4.12 define violación de seguridad como cualquier acceso NO autorizado a datos personales, aunque no salgan del sistema. Y el Art. 33.1 obliga a notificar a la AEPD en 72h SALVO que sea improbable que la violación suponga un riesgo. La carga de la prueba está del lado de no notificar: hay que argumentar por qué el riesgo es improbable, no dar por hecho que sin salida no lo hay. Con hasta 12.847 pacientes identificados junto a sus diagnósticos (categoría especial) vistos por alguien sin autorización, sostener que el riesgo es improbable es muy difícil. La lectura prudente aquí es que probablemente SÍ hay que notificar; como mínimo, la decisión la toma el DPO por escrito, argumentando el riesgo, y no el ingeniero asumiendo que "como no salió, no pasa nada".

## El post-mortem del incidente

Laura te pide que redactes el post-mortem técnico del incidente. Es un documento interno que queda en el registro de seguridad. Debe ser factual, sin juicios de valor, y con acciones correctivas claras:

  • QUE pasó: un junior sacó pacientes identificados con sus diagnósticos crónicos sin autorización ni justificación
  • CUANDO: 18 de septiembre 2024, 14:32:15 UTC (una sola consulta de 4,5 segundos)
  • COMO se detectó: sistema de alertas automático sobre el audit trail (nuevo, implementado esa misma mañana)
  • IMPACTO: 12.847 registros (nombre, DNI, contacto + diagnóstico crónico); es el techo de pacientes afectados, porque un paciente con dos diagnósticos sale dos veces
  • CONTENCION: acceso revocado en 26 minutos desde la detección
  • CAUSA RAIZ: permisos de BD excesivos para rol junior + petición directa de Dr. Martín sin pasar por protocolo
  • DATOS EXFILTRADOS: NO por COPY ni pg_dump -- una SELECT en psql, volcada por pantalla; IT confirma que no hubo ficheros ni envíos
  • NOTIFICACION AEPD: SI -- acceso no autorizado a datos de salud (Art. 4.12) con riesgo no improbable (Art. 33.1); se notifica en 72h aunque no hubiera exfiltracion
  • ACCIONES CORRECTIVAS: implementar RLS, formación GDPR obligatoria, canal formal para peticiones de datos

Regístrate para guardar tu progreso.