Volver al blog

Filtración de 153 Millones de Documentos: Qué Cambia Para Quien Pide Foto de Identidad

Hola HaWkers, el 1 de septiembre de 2026 el periodista Brian Krebs publicó que un servicio nuevo en la dark web, llamado Nexus, estaba vendiendo imágenes digitalizadas de más de 153 millones de licencias de conducir de Estados Unidos y Canadá. Junto a ellas venían más de 10 millones de tarjetas de identidad, más de 3 millones de documentos de viaje y cerca de 579 mil credenciales médicas. El propio Krebs encontró su licencia, emitida en el estado de Virginia, ofrecida como muestra gratis.

¿Alguna vez te has puesto a pensar en cuántos buckets guardan, ahora mismo, la foto de tu documento porque alquilaste un coche, entraste a un hotel o abriste una cuenta? En este artículo te muestro qué se sabe del caso, por qué la arquitectura más común de verificación de identidad acumula ese riesgo, y qué puedes cambiar en tu código esta misma semana para no convertirte en el próximo titular.

Qué Pasó: 153 Millones de Documentos y un Proveedor en el Medio

El rastro apunta a una sola empresa. Con base en entrevistas con personas cuyas licencias estaban a la venta, el origen probable de las imágenes es IDScan.net, una empresa de verificación de identidad con sede en Nueva Orleans, Luisiana, que valida documentos para clientes como Hertz, FedEx, Caesars Entertainment y una larga lista de dispensarios de cannabis en Estados Unidos.

Dos detalles técnicos cierran el cerco. Los registros no traían solo la foto del frente y del reverso: traían también los escaneos en infrarrojo y ultravioleta que hacen los lectores profesionales para comprobar los elementos de seguridad del plástico. Y traían marcas de tiempo que coinciden con el momento en que esas personas alquilaron un coche o viajaron. Ninguna filtración de una base de datos suelta en internet produce ese conjunto: eso es lo que sale de un equipo de captura, en el punto de atención, camino a la nube.

El vendedor afirmaba estar exfiltrando datos de forma continua desde hacía más de un año, con el acervo actualizándose todo el tiempo, y llegó a anunciar casi 400 mil licencias nuevas añadidas en 24 horas. Para darle dimensión pública al catálogo, la licencia del secretario de Defensa de Estados Unidos, Pete Hegseth, emitida en Minnesota, fue listada por 100 dólares.

La oficina del FBI en Nueva Orleans abrió una investigación oficial sobre el origen de las imágenes, y Krebs relató que lo pusieron en una llamada con media docena de agentes, incluyendo liderazgos de la división cibernética. Gillian Cossman, directora de operaciones de IDScan.net, confirmó que la empresa investigaba el incidente. El sitio Nexus salió del aire poco después del reportaje, lo que no devuelve nada: quien compró, ya compró.

Por Qué el Proveedor de Verificación Es el Blanco Perfecto

La economía de la verificación de identidad se organizó como casi todo nuestro stack: en lugar de que cada empresa construya su propia lectura de documentos, todas se enchufan al mismo puñado de proveedores. Es la decisión correcta en calidad de detección de fraude, y es la decisión que concentra todo el riesgo en un solo punto.

Piensa en lo que eso significa en volumen. Una arrendadora de coches sola quizá guarde algunos millones de documentos. Un proveedor que atiende a la arrendadora, al hotel, al recinto de conciertos, al dispensario y al banco guarda la intersección de todos ellos, que en el límite es la población adulta de dos países. El atacante ya no necesita elegir un objetivo: elige al proveedor.

El segundo problema es el tiempo. Una contraseña filtrada la cambias en 30 segundos. Un número de tarjeta el banco lo reemite en tres días. Una licencia de conducir con foto, número, fecha de nacimiento, dirección y firma vale por los próximos cinco o diez años, y la única forma de "cambiarla" es mudarse de estado. Ese es el motivo de que la imagen de un documento sea una categoría de dato distinta de todas las demás que guardas: no caduca y no tiene revocación.

Y existe un tercero, más incómodo: casi nadie sabe dónde viven las imágenes. Cuando subes tu identidad en una app, tienes una relación con esa marca. La imagen, en la práctica, se fue a su subprocesador, que quizá use un almacenamiento de terceros, que replica en otra región. Fue exactamente esa cadena la que expuso el caso Nexus: las víctimas nunca habían oído hablar de IDScan.net.

El Error de Arquitectura: Guardar la Imagen Después de la Verificación

Aquí está el punto que le interesa a quien escribe código. En la abrumadora mayoría de los productos, la foto del documento es un insumo de una decisión binaria: esta persona tiene más de 18 años, este nombre coincide con el de la tarjeta, este documento es auténtico. La decisión es lo que el negocio necesita. La imagen es el residuo.

Solo que el flujo estándar hace lo contrario: sube la imagen a un bucket, corre la verificación, graba el resultado en una columna y deja la imagen ahí, "por si acaso", "por auditoría", "porque compliance puede pedirla". Años después nadie recuerda que el bucket existe, y ahora tiene 40 millones de objetos.

El patrón sano es invertirlo: la imagen es efímera, el veredicto es persistente. En TypeScript, dentro de un handler de subida, eso es menos trabajo de lo que parece.

// Verificación en memoria: la imagen nunca llega a un bucket.
import { randomUUID, createHash } from 'node:crypto';

type Veredicto = {
  id: string;
  usuarioId: string;
  mayorDeEdad: boolean;
  nombreCoincide: boolean;
  documentoAutentico: boolean;
  emisorEstado: string; // atributo derivado, no el documento
  proveedor: string;
  verificadoEn: string;
  // Huella digital para deduplicar intentos sin guardar la imagen.
  digestImagen: string;
};

export async function verificarDocumento(
  usuarioId: string,
  imagen: Buffer,
  nombreEsperado: string
): Promise<Veredicto> {
  // 1. Lo manda al proveedor y recibe solo atributos.
  const analisis = await proveedorKyc.analizar(imagen);

  // 2. Extrae lo que el negocio realmente necesita.
  const veredicto: Veredicto = {
    id: randomUUID(),
    usuarioId,
    mayorDeEdad: analisis.edad >= 18,
    nombreCoincide: normalizar(analisis.nombre) === normalizar(nombreEsperado),
    documentoAutentico: analisis.scoreAutenticidad > 0.9,
    emisorEstado: analisis.estado,
    proveedor: 'proveedor-x',
    verificadoEn: new Date().toISOString(),
    digestImagen: createHash('sha256').update(imagen).digest('hex'),
  };

  // 3. Descarta la imagen antes de responder. Sin bucket, sin cola, sin log.
  imagen.fill(0);

  return veredicto;
}

Fíjate en lo que quedó: ninguna fecha de nacimiento, ningún número de documento, ninguna foto. Si esa base se filtra mañana, el atacante se lleva booleanos. Y el digestImagen todavía permite responder "¿este mismo documento ya fue usado en otra cuenta?" sin conservar el documento.

Si Necesitas Guardarla, Guárdala Con Fecha de Caducidad

Existen casos legítimos de retención. Las instituciones financieras tienen obligaciones de custodia, y las disputas de chargeback piden evidencia. La respuesta no es "nunca guardes", es "guarda con plazo, con clave por registro y con borrado automático".

La clave por registro importa porque cambia la economía de la filtración. Con una clave única para el bucket entero, quien obtiene la clave lo obtiene todo. Con envelope encryption, cada documento tiene su propia clave de datos, cifrada por la clave maestra del KMS. El atacante que copia el bucket se lleva bytes aleatorios.

// Envelope encryption + expiración: el registro se destruye solo.
import { KMSClient, GenerateDataKeyCommand } from '@aws-sdk/client-kms';
import { createCipheriv, randomBytes } from 'node:crypto';

const kms = new KMSClient({});
const RETENCION_DIAS = 90;

export async function guardarConPlazo(imagen: Buffer, registroId: string) {
  // Una clave de datos nueva para cada documento.
  const { Plaintext, CiphertextBlob } = await kms.send(
    new GenerateDataKeyCommand({ KeyId: 'alias/documentos', KeySpec: 'AES_256' })
  );

  const iv = randomBytes(12);
  const cipher = createCipheriv('aes-256-gcm', Plaintext!, iv);
  const cifrado = Buffer.concat([cipher.update(imagen), cipher.final()]);

  await s3.putObject({
    Bucket: 'documentos-kyc',
    Key: `${registroId}.bin`,
    Body: Buffer.concat([iv, cipher.getAuthTag(), cifrado]),
    // La expiración vive en el objeto, no en una hoja de cálculo de proceso.
    Expires: new Date(Date.now() + RETENCION_DIAS * 864e5),
    Metadata: { clave: CiphertextBlob!.toString('base64') },
  });

  // Pone la clave en claro a cero en cuanto termina su uso.
  Plaintext!.fill(0);
}

Complétalo con una regla de ciclo de vida en el bucket que borre de verdad los objetos después del plazo. Una política declarada en la infraestructura sobrevive al cambio de equipo; una rutina de limpieza escrita a mano muere en el primer deploy que nadie revisó.

El Metadato Que Nadie Mira

El caso Nexus tiene una lección fácil de aplicar y fácil de olvidar: los registros a la venta contenían marca de tiempo y los escaneos en infrarrojo y ultravioleta. O sea, junto con la identidad se filtró el contexto: dónde y cuándo estaba esa persona.

Lo mismo pasa en tu formulario de subida. Una foto tomada con el móvil llega con EXIF: modelo del aparato, fecha, hora y, con frecuencia, coordenadas de GPS. Si almacenas el archivo tal como lo recibiste, no guardaste un documento, guardaste un documento más la ubicación de quien lo envió.

// Normaliza la imagen y descarta todo metadato antes de cualquier persistencia.
import sharp from 'sharp';

export async function higienizar(entrada: Buffer): Promise<Buffer> {
  return sharp(entrada)
    .rotate() // aplica la orientación y después tira el EXIF a la basura
    .resize({ width: 1600, withoutEnlargement: true })
    .jpeg({ quality: 82, mozjpeg: true })
    .withMetadata({ exif: {} }) // sin GPS, sin dispositivo, sin timestamp
    .toBuffer();
}

Vale la misma disciplina para los logs. Un console.log(req.body) en un handler de subida manda la imagen entera, en base64, al agregador de logs, que suele tener retención más larga y control de acceso más flojo que la base de datos. Ahí la filtración ni siquiera necesita un atacante sofisticado.

Verificación de Edad Sin Pedir el Documento

La pregunta más honesta es anterior a todo esto: ¿de verdad necesitas la imagen? Para una porción grande de los casos, verificar mayoría de edad, confirmar residencia en un país, probar que la persona tiene licencia válida, la respuesta en 2026 es no.

La Digital Credentials API del W3C llegó a Chrome 141 y a Safari 26 en septiembre de 2025, y Firefox ya carga una implementación básica. Habla con la cartera del sistema operativo y usa el formato mdoc, de la norma ISO/IEC 18013-5, la misma que sostiene las licencias de conducir digitales por todo el mundo. La segunda edición de la norma está en votación, con publicación prevista para el tercer trimestre de 2026.

Lo que cambia para tu código es la divulgación selectiva: pides un atributo, no un documento.

// Pide solo "es mayor de 18", nunca el número ni la dirección.
const respuesta = await navigator.credentials.get({
  digital: {
    requests: [
      {
        protocol: 'openid4vp',
        data: {
          response_type: 'vp_token',
          nonce: nonceDelServidor, // generado en el backend, de un solo uso
          dcql_query: {
            credentials: [
              {
                id: 'licencia',
                format: 'mso_mdoc',
                meta: { doctype_value: 'org.iso.18013.5.1.mDL' },
                // La petición entera cabe en un campo booleano.
                claims: [{ path: ['org.iso.18013.5.1', 'age_over_18'] }],
              },
            ],
          },
        },
      },
    ],
  },
});

// Llega una prueba firmada de "true". No llega foto, ni número, ni fecha.
await fetch('/api/edad', { method: 'POST', body: JSON.stringify(respuesta.data) });

La credencial queda cifrada en el dispositivo, y lo que viaja es una prueba firmada del atributo. No existe imagen que filtrar porque no existe imagen. Ese es el mismo debate que apareció en la ley californiana AB 1856 sobre verificación de edad: la regulación empuja a las plataformas a verificar, y el modo en que verifican decide si el resultado es protección o un pasivo de 153 millones de registros.

Qué Preguntar Antes de Enchufar un Proveedor

Si la verificación se va a un tercero, y casi siempre se va, el contrato es parte de la arquitectura. Cuatro preguntas resuelven la mayor parte:

  • ¿Ustedes retienen la imagen después del veredicto? ¿Por cuánto tiempo, y cómo fuerzo el borrado? Si la respuesta es vaga, la respuesta es "para siempre".
  • ¿Quiénes son los subprocesadores y en qué regiones quedan los datos? La lista tiene que estar escrita y versionada, no en una conversación de ventas.
  • ¿El cifrado es por registro o por bucket? Eso decide si un acceso indebido cuesta un documento o todos.
  • ¿Existe una API para eliminación bajo demanda, y borra los backups? Bajo el GDPR y leyes equivalentes tú eres el responsable del tratamiento. La obligación de atender al titular es tuya, aunque el dato esté con el proveedor.

Súmale a eso la higiene básica: credencial de API del proveedor con rotación, alcance mínimo y alerta de volumen. El vendedor de Nexus decía exfiltrar desde hacía más de un año, con 400 mil registros en 24 horas. Un gráfico de lecturas por credencial habría gritado mucho antes.

Qué Hacer Del Lado de Acá

Como usuario, lo que puedes hacer es limitado, pero no es nada. Pregunta por qué un establecimiento necesita copiar tu documento y qué pasa con la copia. Prefiere la credencial digital o la lectura en el local en vez de mandar la foto por correo o WhatsApp. Activa la alerta de crédito en los burós. Y desconfía de contactos que citan datos correctos de tu documento: con un acervo así, el fraude de ingeniería social queda convincente por defecto.

El punto más amplio es el mismo que discutí en el post sobre la demanda de WhatsApp en torno al cifrado de extremo a extremo: dato que existe es dato que puede ser pedido, robado o vendido. La única protección que no depende de la competencia de terceros es el dato que nunca fue recolectado.

Qué Deja Esto Para 2026

Tres lecturas prácticas.

La primera es que la era del "sube la foto del documento" está llegando a su fin, y no por bondad: está saliendo cara. Los reguladores europeos ya tratan la retención de imágenes de documentos como desproporcionada cuando existe alternativa técnica, y ahora existe alternativa técnica en navegador estable.

La segunda es que la verificación de identidad se volvió una dependencia crítica, del mismo nivel que un proveedor de pagos. Merece plan de contingencia, revisión de contrato y monitoreo de volumen, no una integración hecha en un sprint y nunca más tocada.

La tercera es la más directa. Abre hoy el inventario de dónde tu producto guarda imágenes de documentos. Mide cuántos objetos existen, desde cuándo, y cuántos seguirían siendo necesarios si borraras todo lo que pasó del plazo. En la mayoría de los equipos esa cuenta asusta, y es justamente por eso que vale la pena hacerla antes de que alguien de fuera la haga por ti.

¡Vamos con todo! 🦅

📚 ¿Quieres Seguir lo Que Viene Por Delante?

Este artículo cubrió la filtración de 153 millones de documentos y lo que cambia en la verificación de identidad, pero el ecosistema cambia cada semana y no todo se convierte en artículo aquí.

En X comparto lo que estoy probando, el detrás de cámaras de los proyectos y las novedades que aparecen antes de volverse post.

Sígueme Allá

👉 Seguir a @jeffbruchado en X

💡 Contenido diario sobre desarrollo, carrera y las herramientas que realmente uso

Comentarios (0)

Este artículo aún no tiene comentarios 😢. ¡Sé el primero! 🚀🦅

Añadir comentarios