Esta semana Google ha publicado una corrección de seguridad para el motor de red de Dart, incluida tanto en el parche Flutter 3.47.8 como en Flutter 3.50 (estable desde el 11 de noviembre). Si tienes una app Flutter en producción para Android, Windows o Linux, la respuesta corta es: actualiza el SDK, recompila y vuelve a publicar. En iOS, macOS y web no te afecta. El resto del artículo explica por qué, a quién corre más prisa y qué no arregla el problema (ni una actualización OTA ni parchear tu portátil).

Qué ha pasado

En octubre se descubrió que ocho certificados intermedios de la autoridad eMudhra se habían generado con una entropía ridícula. Tanto que una de las claves privadas resultó ser el número 4 — el cuatro, sin más. Con la clave pública a la vista, cualquiera podía derivar la privada y firmar un certificado HTTPS válido para cualquier dominio, no solo para los que eMudhra tenía permiso de emitir. Google lo detectó, Chrome bloqueó los intermedios por su hash y eMudhra empezó a revocar: ocho el 18 de octubre y otros ocho el 7 de noviembre. La empresa ha anunciado además que abandona el negocio de certificados TLS de confianza pública, y Microsoft retira sus raíces de sus productos a partir del 16 de noviembre.

Hasta aquí es un incidente de CA más, de los que el navegador y el sistema operativo resuelven solos. El matiz que afecta a Flutter es otro: dart:io no usa el almacén de confianza del sistema. Trae el suyo, basado en BoringSSL, con su propia lista de CA raíz compilada dentro. Es la misma pila que usan por debajo http, dio, los sockets y los WebSockets. Así que mientras Chrome y Android ya habían dejado de confiar en esos intermedios, cualquier app Flutter que hiciera peticiones por dart:io seguía confiando en ellos. De ahí el aviso GHSA-frr6-h895-5pxp, clasificado como de severidad alta: un atacante en la red podría interponerse (man-in-the-middle) presentando un certificado forjado que tu app daría por bueno.

Conviene ser honesto con el alcance: no hay constancia de que se haya explotado. No se registró ningún certificado encadenado a esas CA en los logs de Certificate Transparency antes del bloqueo. Es un riesgo latente, no un incendio declarado. Eso cambia la urgencia, no la decisión.

A quién afecta y a quién no

Plataforma¿Afectada?Por qué
AndroidSídart:io con su almacén BoringSSL propio
WindowsSíIgual
LinuxSíIgual, sobre todo contenedores o sistemas sin parchear
iOSNoLa red va contra el almacén de confianza del sistema
macOSNoIgual
Flutter webNoUsa el TLS del navegador

En iOS y macOS, Apple actualiza el almacén de confianza por su cuenta y tu app se beneficia sin tocar nada. En Android, Windows y Linux el almacén viaja dentro de tu binario. Lo fijaste tú el día que compilaste.

Qué implica para tu producto

Mucha gente va a pasar por alto esto: el parche va compilado dentro de tu binario. Actualizar Flutter y Dart en tu máquina protege las builds que hagas a partir de ahora, no las que tus usuarios ya tienen instaladas. Para cerrar el agujero de verdad hay que recompilar y publicar una versión nueva.

Y no, una actualización over-the-air no te salva. Shorebird y similares empujan código Dart, no el motor nativo ni la pila TLS que vive debajo. Este fallo está justo en esa capa. Si tu plan de respuesta ante incidentes daba por hecho que un code push resuelve cualquier cosa, aquí tienes dónde está el límite.

Para una app de consumo el ciclo es: subir versión, pasar revisión de tienda, esperar a que la gente actualice. Para un despliegue interno de Windows o Linux depende de tu MDM o de tu pipeline. En ningún caso es instantáneo, y por eso conviene empezar ya aunque no haya pánico.

Hay un segundo frente, aparte de la app: revisa la cadena de certificados de tu propio backend. Si encadena por emSign ECC Root CA - G3 (que Chrome retiró de su Root Store el 27 de octubre), reemítelo desde otra raíz o los clientes basados en Chrome dejarán de conectar.

Nuestra recomendación

Para quien tenga una app Flutter en producción en Android, Windows o Linux, y en especial si maneja datos sensibles (fintech, salud, cualquier cosa con sesión autenticada), esto es trabajo de esta semana, no del próximo sprint. Los pasos son cortos:

flutter --version   # ¿estás por debajo de 3.47.8?
flutter upgrade     # arrastra Dart 3.13.7 o superior
flutter clean && flutter build appbundle   # recompila

Versiones parcheadas: Flutter 3.47.8 (estable) o 3.50.0-0.2.pre (beta); Dart 3.13.7 (estable) o 3.14.0-315.3.beta. flutter upgrade trae la versión de Dart correcta.

Para quien solo tenga app en iOS o web, puedes respirar: no te afecta. Pero anota la lección igualmente, porque la próxima CA que se caiga te encontrará en la misma situación. Que dart:io traiga su propio almacén de confianza es cómodo (comportamiento idéntico en todas las plataformas) y a la vez una responsabilidad: tu app carga una foto congelada de en quién confía el día que la compilaste. Mantener eso fresco es parte del mantenimiento, igual que las dependencias o el target SDK.

Lo que no haríamos: ni ignorarlo porque "no hay explotación conocida" (la hay o no la hay hasta que la hay), ni desactivar la verificación de certificados con un override para salir del paso. Eso cambia un riesgo latente por uno garantizado.

Si quieres que miremos qué versión de Flutter corre en tu app, cómo tienes montada la cadena de confianza y cuánto cuesta sacar una build de seguridad sin romper producción, hablamos. Es justo el tipo de fuego controlado que llevamos manteniendo apps desde 2011.