Falsos positivos de seguridad
Vulnerabilidades de seguridad reportadas incorrectamente por herramientas automatizadas de análisis estático.
Introducción
#De vez en cuando recibimos informes falsos de vulnerabilidades de seguridad en aplicaciones Dart y Flutter, generados por herramientas que fueron creadas para otros tipos de aplicaciones (por ejemplo, aquellas escritas en Java o C++). Este documento proporciona información sobre los informes que consideramos incorrectos y explica por qué estas preocupaciones son infundadas.
Preocupaciones comunes
#Los objetos compartidos deberían usar funciones fortalecidas
#El objeto compartido no tiene funciones fortificadas. Las funciones fortificadas proporcionan comprobaciones de desbordamiento de búfer contra funciones inseguras comunes de glibc como
strcpy,gets, etc. Usa la opción del compilador-D_FORTIFY_SOURCE=2para fortificar funciones.
Cuando esto se refiere a código Dart compilado
(como el archivo libapp.so en aplicaciones de Flutter),
este consejo es desacertado porque el código de Dart no
invoca directamente funciones de libc;
todo el código de Dart pasa a través de la biblioteca estándar de Dart.
(En general, MobSF obtiene falsos positivos aquí porque
busca cualquier uso de funciones con el sufijo _chk,
pero dado que Dart no usa estas funciones en absoluto,
no tiene llamadas con o sin el sufijo y,
por lo tanto, MobSF trata el código como si contuviera
llamadas no fortalecidas).
Los objetos compartidos deberían usar RELRO
#no se encontró RELRO para los binarios
libapp.so
Dart no utiliza en absoluto los mecanismos habituales de Procedure Linkage Table (PLT) o Global Offsets Table (GOT), por lo que la técnica Relocation Read-Only (RELRO) realmente no tiene mucho sentido para Dart.
El equivalente de GOT en Dart es el puntero de pool (pool pointer), el cual, a diferencia de GOT, se encuentra en una ubicación aleatoria y, por lo tanto, es mucho más difícil de explotar.
En principio, puedes crear código vulnerable al usar Dart FFI, but el uso normal de Dart FFI tampoco sería propenso a estos problemas, asumiendo que se utilice con código C que a su vez use RELRO de manera adecuada.
Los objetos compartidos deberían usar valores stack canary
#no se encontraron valores stack canary para los binarios
libapp.so
Este objeto compartido no tiene un valor stack canary añadido a la pila. Los valores stack canary se utilizan para detectar y prevenir exploits que sobrescriban la dirección de retorno. Usa la opción -fstack-protector-all para habilitar los stack canaries.
Dart no genera stack canaries porque, a diferencia de C++, Dart no tiene arreglos (arrays) asignados en la pila (la fuente principal de desbordamiento de pila en C/C++).
Al escribir Dart puro (sin usar dart:ffi),
ya cuentas con garantías de aislamiento mucho más sólidas
que las que puede proporcionar cualquier mitigación de C++,
simplemente porque el código de Dart puro es un lenguaje administrado (managed)
en el que no existen problemas como los desbordamientos de búfer (buffer overruns).
En principio, puedes crear código vulnerable al usar Dart FFI, pero el uso normal de Dart FFI tampoco sería propenso a estos problemas, siempre que se use con código C que a su vez emplee valores stack canary adecuadamente.
El código debería evitar el uso de las API _sscanf, _strlen y _fopen
#
El binario puede contener las siguientes API(s) inseguras:
_sscanf,_strlen,_fopen.
Las herramientas que informan estos problemas suelen ser demasiado simplistas en sus análisis; por ejemplo, encuentran funciones personalizadas con estos nombres y asumen que se refieren a las funciones de la biblioteca estándar. Muchas de las dependencias de terceros de Flutter tienen funciones con nombres similares que activan estas alertas. Es posible que algunas ocurrencias sean preocupaciones válidas, pero es imposible saberlo a partir del resultado de estas herramientas debido a la gran cantidad de falsos positivos.
El código debería usar calloc (en lugar de _malloc) para las asignaciones de memoria
#
El binario podría usar la función
_mallocen lugar decalloc.
La asignación de memoria es un tema complejo,
en el que se deben hacer concesiones entre el rendimiento
y la resistencia a las vulnerabilidades.
El simple hecho de utilizar malloc no es automáticamente indicativo
de una vulnerabilidad de seguridad.
Aunque recibimos con agrado informes concretos (ver más abajo)
para los casos en que sería preferible usar calloc,
en la práctica sería inadecuado reemplazar uniformemente
todas las llamadas a malloc por calloc.
El binario de iOS tiene configurado un Runpath Search Path (@rpath)
#
El binario tiene configurado un Runpath Search Path (
@rpath). En ciertos casos, un atacante puede abusar de esta función para ejecutar un ejecutable arbitrario con el fin de ejecutar código y lograr una escalada de privilegios. Elimina la opción de compilador-rpathpara remover@rpath.
Cuando se compila la aplicación, Runpath Search Path hace referencia
a las rutas en las que el enlazador (linker) busca para encontrar bibliotecas dinámicas
(dylibs) utilizadas por la aplicación.
De forma predeterminada, las aplicaciones de iOS tienen esto configurado como
@executable_path/Frameworks,
lo que significa que el enlazador debe buscar dylibs
en el directorio Frameworks relativo al binario de la aplicación
dentro del bundle de la aplicación.
El motor (engine) Flutter.framework,
al igual que la mayoría de los frameworks integrados o dylibs,
se copia correctamente en este directorio.
Cuando la aplicación se ejecuta, carga el binario de la biblioteca.
Las aplicaciones de Flutter utilizan la configuración de compilación de iOS predeterminada
(LD_RUNPATH_SEARCH_PATHS=@executable_path/Frameworks).
Las vulnerabilidades relacionadas con @rpath no se aplican
en entornos móviles, ya que los atacantes no tienen
acceso al sistema de archivos y no pueden reemplazar
arbitrariamente estos frameworks.
Incluso si un atacante de alguna manera pudiera reemplazar el
framework por uno malicioso,
la aplicación fallaría al iniciarse debido a violaciones de la firma de código.
Vulnerabilidad de CBC con relleno (padding) PKCS5/PKCS7
#Hemos recibido informes vagos sobre la existencia de una "vulnerabilidad de CBC con relleno (padding) PKCS5/PKCS7" en algunos paquetes de Flutter.
Por lo que sabemos, esto es provocado por la HLS
implementación en ExoPlayer
(la clase com.google.android.exoplayer2.source.hls.Aes128DataSource).
HLS es el formato de streaming de Apple,
el cual define el tipo de cifrado que debe usarse para DRM;
esto no es una vulnerabilidad,
ya que el DRM no protege la máquina ni los datos del usuario,
sino que simplemente proporciona ofuscación
para limitar la capacidad del usuario de utilizar plenamente su software y hardware.
Las aplicaciones pueden leer y escribir en el almacenamiento externo
#La aplicación puede leer/escribir en el almacenamiento externo. Cualquier aplicación puede leer los datos escritos en el almacenamiento externo.
Al igual que con los datos de cualquier fuente no confiable, debes realizar una validación de entrada cuando manejes datos del almacenamiento externo. Te recomendamos encarecidamente que no almacenes ejecutables o archivos de clase en el almacenamiento externo antes de la carga dinámica. Si tu aplicación recupera archivos ejecutables del almacenamiento externo, los archivos deben firmarse y verificarse criptográficamente antes de la carga dinámica.
Hemos recibido informes de que algunas herramientas de escaneo de vulnerabilidades interpretan la capacidad de los plugins de selección de imágenes (image picker) para leer y escribir en el almacenamiento externo como una amenaza.
Leer imágenes del almacenamiento local es el propósito de estos plugins; esto no es una vulnerabilidad.
Las aplicaciones eliminan datos usando file.delete()
#Cuando eliminas un archivo usando file.delete(), solo se elimina la referencia al archivo de la tabla del sistema de archivos. El archivo sigue existiendo en el disco hasta que otros datos lo sobrescriban, dejándolo vulnerable a la recuperación.
Algunas herramientas de escaneo de vulnerabilidades interpretan la eliminación de archivos temporales después de que un plugin de cámara graba datos de la cámara del dispositivo como una vulnerabilidad de seguridad. Dado que el video es grabado por el usuario y se almacena en el hardware del usuario, no existe un riesgo real.
Preocupaciones obsoletas
#Esta sección contiene mensajes válidos que podrían verse con versiones anteriores de Dart y Flutter, pero que ya no deberían aparecer en versiones más recientes. Si ves estos mensajes con versiones antiguas de Dart o Flutter, actualiza a la última versión estable. Si los ves con la versión estable actual, por favor repórtalos (consulta la sección al final de este documento).
La pila (stack) debería tener configurado su bit NX
#El objeto compartido no tiene configurado el bit NX. El bit NX ofrece protección contra la explotación de vulnerabilidades de corrupción de memoria al marcar la página de memoria como no ejecutable. Usa la opción
--noexecstacko-z noexecstackpara marcar la pila como no ejecutable.
(El mensaje de MobSF es engañoso; está buscando si la pila está marcada como no ejecutable, no el objeto compartido).
En versiones anteriores de Dart y Flutter había un error
donde el generador ELF no emitía el segmento gnustack
con el permiso ~X, pero esto ya ha sido solucionado.
Reportar preocupaciones reales
#Aunque las herramientas automatizadas de escaneo de vulnerabilidades informan falsos positivos como los ejemplos anteriores, no podemos descartar que existan problemas reales que merezcan una atención más detallada. Si encuentras un problema que consideres una vulnerabilidad de seguridad legítima, te agradeceríamos enormemente que lo reportaras:
A menos que se indique lo contrario, la documentación de este sitio refleja Flutter 3.44.0. Página actualizada por última vez el 2026-05-05. Ver código fuente oreportar un problema.