Seguridad
La superficie de ataque de un navegador se divide en dos: el motor, que no hemos escrito nosotros, y el shell, que sí. Los dos se comportan de forma muy distinta, así que los explicamos por separado. Las carencias conocidas de esta versión están al final de la página.
El motor: Chromium, V8, Skia
A lo largo de 2026 se corrigieron en Chrome decenas de fallos de seguridad de memoria, seis de ellos zero-days explotados en la práctica. Este código no lo escribimos nosotros y no podemos arreglarlo; aquí la única defensa es mantener el motor al día.
Por eso nuestra regla es tajante: Girginos Browser no se publica sobre una versión de Electron que haya llegado al final de su vida útil. Electron solo mantiene sus tres últimas versiones principales, y la versión fijada se comprueba antes de cada publicación. Ahora mismo usamos Electron 44.2.0 con Chromium 152.0.7977.76.
El shell: el código que hemos escrito nosotros
Estas son las decisiones de arquitectura del lado del shell:
- Cada pestaña es una WebContentsView independiente. El contenido de las páginas se ejecuta con sandbox: true, contextIsolation: true y nodeIntegration: false, y no recibe ningún script de precarga.
- La ventana de la interfaz también se ejecuta en el sandbox y comparte sesión con las pestañas; así, las solicitudes propias de la interfaz también pasan por el bloqueador y llevan las cabeceras DNT.
- Los canales IPC solo se aceptan desde el marco principal de la ventana de la interfaz. Las escrituras de ajustes pasan por una validación de clave y de tipo.
- Las descargas se direccionan mediante un identificador; una ruta de archivo en bruto procedente de la interfaz no se abre nunca.
- La navegación iniciada por la página se limita a http(s) y view-source:http(s). file: y chrome: solo se abren si el usuario los escribe él mismo en la barra de direcciones.
- El traspaso a una aplicación externa se limita a una lista estrecha de esquemas: mailto:, tel:, sms:, magnet:, ftp(s):, webcal:. Solo puede haber un cuadro de confirmación abierto a la vez.
- Los orígenes opacos, aquellos cuyo origen es null, como data: y about:, se rechazan siempre en las solicitudes de permiso.
- La corrección ortográfica está desactivada, porque Chromium descarga sus archivos de diccionario de un servidor de Google.
- Los datos se escriben de forma atómica, mediante un archivo temporal y un cambio de nombre.
Vectores de ataque y respuestas
| Clase | Ejemplo | Respuesta |
|---|---|---|
| Suplantación de la barra de direcciones | RLO/bidi, CR-LF, NUL, bank.com@evil.com, relleno con espacios, homógrafos IDN | Los caracteres invisibles y los espacios se dejan codificados en porcentaje, las credenciales se ocultan y se muestra el punycode |
| Ocultación del dominio | accounts.google.com.giris.evil.com | El dominio registrable se escribe a plena intensidad y el resto se atenúa |
| Imitación de una página interna | newtab.html, una copia descargada | La dirección completa debe coincidir; no se busca por subcadenas |
| Suplantación de la interfaz a pantalla completa | una página pasa a pantalla completa y dibuja una barra de herramientas falsa | La vista de la página nunca se agranda por encima del shell |
| Salto de esquema | file:, chrome:, blob:, view-source:file: | En la navegación iniciada por la página, solo http(s) |
| Llamada a una aplicación externa | ms-msdt:, search-ms:, ms-appinstaller: | Lista de permitidos estrecha y un único cuadro de confirmación |
| Trucos con el nombre de la descarga | evil.exe / evil.exe., punto o espacio final, extensión oculta con RLO | Normalización antes de comprobar la extensión; la decisión se toma según el nombre real en disco |
| Evasión del bloqueador | izleyici.com., punto final | Normalización del host |
La cadena de actualización firmada
El modelo de amenaza da por hecho que el servidor de actualizaciones puede estar ya comprometido. La secuencia funciona así:
- Se descargan el manifiesto firmado y el archivo de firma que lo acompaña.
- La firma se verifica sobre los bytes en bruto del manifiesto con la clave pública Ed25519 incrustada en la aplicación. Si no pasa, no se lee ni un solo campo.
- Se aplican los controles de versión: se rechazan las vueltas a versiones anteriores; se rechaza un manifiesto que haya superado su propia fecha de caducidad, lo que protege frente a un atacante que sirviera eternamente un manifiesto antiguo para congelar las actualizaciones; se exige una versión intermedia cuando hace falta; y la dirección de descarga tiene que ser https.
- La versión y el resumen del paquete que encuentra el descargador deben coincidir exactamente con los del manifiesto firmado.
- Cuando termina la descarga, el resumen sha512 del paquete se compara con el resumen firmado en tiempo constante.
- La instalación solo empieza cuando el usuario da su aprobación.
Si falla cualquiera de los pasos, no hay actualización. La clave privada nunca está en el servidor; aunque el servidor cayera en manos ajenas, un atacante no podría producir un manifiesto válido.
Pruebas
Se ejecutan 118 pruebas unitarias, 73 regresiones de vectores de ataque y 46 pruebas de verificación de actualizaciones, y el contrato IPC y DOM entre la interfaz y el proceso principal se prueba aparte. Además, antes y después de cada publicación se ejecutan scripts de verificación de extremo a extremo sobre los archivos realmente generados y sobre el servidor en producción.
Carencias conocidas
Lo siguiente falta en la 0.1.0. Ocultarlo haría parecer el producto más seguro de lo que es, así que lo decimos abiertamente.
- Sin Mark-of-the-Web
- No se escribe ningún Zone.Identifier en los archivos descargados, por lo que Windows SmartScreen no entra en juego con ellos. El navegador muestra su propio aviso, pero falta la capa del sistema operativo.
- Sin certificado de firma de código
- La firma de código del instalador no se puede verificar. El manifiesto firmado cierra esto para las actualizaciones, pero la primera instalación queda al descubierto.
- Sin Public Suffix List
- En dominios de alojamiento como github.io, las excepciones de sitio y el resaltado de la barra de direcciones abarcan más de lo que deberían.
- Los errores de certificado usan el comportamiento predeterminado de Chromium
- No se ha escrito una pantalla propia de «continuar de todas formas»; con un certificado incorrecto la página sencillamente no se abre.
- El bloqueo es solo a nivel de dominio
- Los rastreadores ocultos tras registros CNAME y los anuncios servidos desde el propio sitio no se detectan, y no se aplica ningún filtro cosmético.