
Detector de fugas de privacidad del navegador — ocho módulos de detección, puntuación de riesgo e historial por cuenta, todo en tu navegador.
Detector de fugas de privacidad del navegador — ocho módulos de detección, puntuación de riesgo e historial por cuenta, todo en tu navegador.
Construido con Verdent — un asistente de codificación agéntico. Cada módulo de detección, el panel de análisis, el flujo de autenticación por clave API, la interfaz bilingüe y la imagen Docker lista para Kubernetes fueron diseñados e implementados en sesiones de programación por pares impulsadas por Verdent.
Abre una URL, haz clic en Run all y, en pocos segundos, Leakish te dice qué
está filtrando tu navegador sobre ti y tu red — a través de WebRTC, APIs de huella
digital, DNS y una sonda del lado del servidor. Ocho módulos independientes producen cada uno un
resultado tipado + señales de riesgo, una puntuación agregada (0–100) y un nivel
(safe / warning / critical).
Los usuarios con sesión iniciada pueden guardar escaneos en MySQL, consultar el historial y abrir un
panel de análisis que muestra gráficos de distribución, repetición de hashes de huella, línea temporal
de IP / ASN, escaneos atípicos y una comparación por pares. Todo lo demás (el propio detector)
funciona sin cuenta: cualquiera puede entrar en /app y ejecutar un escaneo.
Cada módulo se registra a través de una única interfaz tipada DetectionModule<T>
y se ejecuta de forma aislada: que un módulo lance una excepción no afecta a los demás. El estado
de activación de cada módulo se conserva en localStorage con una clave de versión, sobrevive a la
recarga, y el botón Run all solo recorre el conjunto habilitado.
/api/detect/network para leer su propia IP
observada por el servidor, o (c) el módulo DNS se comunica con https://dns.google/resolve.leakish.locale, controla <html lang>, los metadatos de la página, cada pantalla,
cada respuesta de error de la API y el correo de inicio de sesión por magic-link.det_… en la
página Integrations (SHA-256 almacenado, texto plano mostrado una sola vez). Cada
endpoint /api/detect/* acepta una cookie de sesión o una clave Bearer, por lo
que el mismo escaneo puede guardarse desde un trabajo CLI / CI./scans/analytics — gráficos de distribución por
zona horaria / plataforma / idioma / pantalla / WebGL / ASN / país / número de fuentes,
repetición de hashes de huella con una calificación de riesgo por tipo, línea temporal de IP / ASN,
detector de valores atípicos multiejes, comparación por pares con puntuación de similitud 0–100.Requisitos previos: Node 22+ (cualquier versión 20+ sirve para desarrollo local), Yarn 1.x, una instancia de MySQL en ejecución y (opcionalmente) un cliente de Google OAuth.
yarn install
cp env.example .env.local # fill in DATABASE_URL, NEXTAUTH_SECRET, IP_HASH_SALT at minimum
yarn prisma:generate
yarn db:push # provision tables on a fresh DB
yarn dev # http://localhost:3000
Variables de entorno mínimas para que el inicio de sesión funcione:
DATABASE_URL — p. ej. mysql://root:[email protected]:3306/detectNEXTAUTH_SECRET — openssl rand -base64 32NEXTAUTH_URL — http://localhost:3000 en desarrolloIP_HASH_SALT — openssl rand -base64 32Opcional:
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET para el inicio de sesión con GoogleMAILGUN_API_KEY / MAILGUN_DOMAIN / EMAIL_FROM para el envío real de magic-links
(sin estos, el enlace se imprime en la consola del servidor de desarrollo)IPINFO_TOKEN para enriquecer la sonda de red con datos de ASN / VPN / proxyConsulta env.example para la lista completa anotada.
app/
├── (marketing)/ # / — Landing (server-resolved auth state + client UI)
├── app/ # /app — the detector page
├── login/ # /login
├── scans/ # /scans, /scans/[id], /scans/analytics
├── integrations/ # /integrations — API key management
├── api/
│ ├── auth/ # NextAuth route + apiKey-login + tests
│ ├── detect/
│ │ ├── analytics/ # aggregate + pairwise-diff
│ │ ├── network/ # server-side egress probe
│ │ ├── scans/ # save / list / get / delete
│ │ └── uniqueness/ # how many users share this fingerprint hash
│ ├── integration/keys # create / revoke / list API keys
│ └── health/ # liveness probe for k8s
├── opengraph-image.tsx # dynamic OG (per-locale)
├── apple-icon.tsx # dynamic apple-touch icon
├── icon.svg # shield gradient
└── layout.tsx # metadata + theme-init script + LocaleProvider
components/
├── modular-detector.tsx # top-level shell (header + module list + result/overview)
├── detector/ # module-list, result-panel, category filter, state hook
├── result-details/ # one detail view per module (typed switch)
├── overview/ # overview panel + diagnostics export
├── auth/ # AuthGateProvider, login dialog, login form
├── providers/ # SessionProvider wrapper
└── ui/ # shadcn-style primitives + theme/locale toggles
lib/
├── detection-modules/ # 8 module impls + ModuleManager + IP utils + tests
├── risk/ # assess.ts — RiskSignal/score aggregation
├── i18n/ # en.ts / zh.ts + Messages type + locale client/server
├── api/ # withDetectAuth wrapper, scan-payload Zod schema
├── client/ # browser-side scan-api (extractFingerprintInputs, saveScan, lookupUniqueness)
├── server/ # network-probe, IP-hash salt, fingerprint hashing, rate-limit, send-email, analytics
├── persistence/ # SSR-safe localStorage wrappers
├── env.ts # runtime env validation
├── logger.ts # dev-only diagnostic logger
└── prisma.ts # singleton client targeted at .prisma/detect-client
prisma/schema.prisma # User / Account / Session / DetectScan / ApiKey / DetectFingerprintHash
/app. El detector recorre los módulos habilitados a través de ModuleManager.runAllEnabledModules — el fallo de cada módulo se captura y se aísla para que el resto de resultados sigan mostrándose.DetectionResult<T> tipado (con la etiqueta success | failure y data específica del módulo). El panel de resultados renderiza un componente de detalle por módulo mediante un switch type-safe.lib/risk/assess.ts recorre cada resultado, emite RiskSignals con IDs estables y produce un OverallAssessment (puntuación + nivel + conteos).POST a /api/detect/scans. El servidor valida con Zod, ejecuta su propia sonda de red para registrar la IP / ASN / indicadores VPN observados por el servidor, y escribe una fila más filas .Las pruebas unitarias se encuentran junto a sus sujetos en directorios __tests__/:
yarn test # full suite
yarn test path/to/file # single file
yarn test -t "name pattern" # by test-name regex
Destacados:
lib/detection-modules/__tests__/ — clasificación de IP + extracción de mDNS, registro del gestor de módulos y aislamiento de fallos, RTCPeerConnection simulado para el módulo WebRTC, pruebas de forma jsdom para el módulo browser-fingerprint, generación de señales CDP/automatización.lib/server/__tests__/analytics.test.ts — agrupación en cubos de distribución, agrupación de repeticiones, puntuación de valores atípicos, matemática de similitud por pares.app/api/detect/scans/__tests__ — guardado POST (validación, límite de tasa, idempotencia, poda) + listado GET + borrado DELETE individual.app/api/integration/keys/__tests__ — crear / revocar / listar con control de modo (las sesiones con clave API no pueden generar otras claves API).app/api/auth/__tests__ — ruta apiKey-login (CSRF, comprobación de formato, gestión de revocadas / expiradas, actualización de último uso).Lint + comprobación de tipos:
yarn lint
npx tsc --noEmit
La Dockerfile incluida produce una imagen standalone de Next.js sobre node:22-alpine. Las variables de entorno de producción se inyectan mediante Kubernetes Secret — los valores de marcador de posición se incrustan en tiempo de compilación, por lo que SKIP_ENV_VALIDATION no es necesario en tiempo de ejecución. Un Job prisma db push ejecuta el esquema antes del despliegue. Consulta .github/workflows/deploy-tke.yml para ver el pipeline completo de compilación de imagen → migración → despliegue.
Esta versión de código abierto no tiene muro de pago. Los guardados se rigen únicamente por el limitador de tasa por usuario en proceso de lib/server/rate-limit.ts (10 guardados/hora), y la retención del historial es ilimitada.
Consulta LICENSE.
| ID | Módulo | Qué inspecciona |
|---|
network-probe | Sonda de salida de red | IP pública observada por el servidor, ASN, país/región/ciudad, indicadores de VPN/proxy/Tor/hosting, TLS/HTTP |
webrtc | WebRTC | IPv4 + IPv6 públicas vía STUN, fugas RFC1918, candidatos .local ofuscados con mDNS |
browser-fingerprint | Huella del navegador | UA, pantalla, zona horaria, plugins, núcleos de CPU, memoria del dispositivo, lista de idiomas, DNT, cookies |
canvas-fingerprint | Canvas / WebGL | Cadenas de renderizador/fabricante 2D + WebGL, peculiaridades de renderizado de texto, formatos de imagen compatibles |
audio-fingerprint | Audio | Frecuencia de muestreo de AudioContext, canales, latencia, hash de salida del oscilador |
font-detection | Fuentes | Más de 40 sondas de fuentes nombradas mediante detección de diferencia de anchura en Canvas |
dns | DNS | Accesibilidad de DoH, señal DNSSEC, geolocalización del resolutor, heurísticas de fuga DNS |
cdp-detection | Automatización / headless | navigator.webdriver, temporización CDP, superficie de API solo Chromium, sondas de puerto — confianza 0–1 |
lib/risk/assess.tsRiskSignalwebrtc.public-ip-leakMessagesPOST /api/detect/scans acepta una
cabecera Idempotency-Key, limita a cada usuario a 200 escaneos y limita la tasa de
guardados a 10/hora.node:22-alpine,
salida standalone de Next.js, despliegue en Kubernetes mediante el workflow en
.github/workflows/.| Ruta | Propósito |
|---|
/ | Página de aterrizaje de marketing (hero aurora, tarjetas de características, FAQ, CTA) |
/app | El detector — lista de módulos + panel de resultados + vista general |
/login | Página de inicio de sesión independiente (Google / correo / clave API) |
/scans | Historial de escaneos guardados del usuario con sesión iniciada |
/scans/[id] | Detalle de un escaneo guardado |
/scans/analytics | Distribución / repetición / línea temporal / valores atípicos / comparación |
/integrations | Gestionar claves API det_… (crear / revocar / cómo se usa) |
DetectScanDetectFingerprintHash/scans/[id], contribuye a los agregados de análisis y cuenta en la búsqueda de unicidad.| Capa | Componentes |
|---|
| Framework | Next.js 14 (App Router, force-dynamic en todas partes), React 18 |
| Lenguaje | TypeScript 5, modo estricto |
| UI | Tailwind CSS 3, primitivas de shadcn/ui sobre Radix, iconos Lucide, Framer Motion |
| Auth | NextAuth 4 (Google OAuth + correo magic-link) + adaptador Prisma |
| Datos | Prisma 6 → MySQL (salida de cliente personalizada en .prisma/detect-client) |
| Validación | Zod |
| Pruebas | Jest 29 + ts-jest + jsdom |
| Compilación / despliegue | Dockerfile multi-etapa, Next.js standalone, manifiestos de Kubernetes |