Categoría de OWASP: MASVS-CODE: Calidad de código
Descripción general
Las aplicaciones para Android pueden aprovechar el código nativo escrito en lenguajes como C y C++ para funcionalidades específicas. Sin embargo, cuando una aplicación utiliza la interfaz nativa de Java (JNI) para interactuar con este código nativo, se expone potencialmente a vulnerabilidades como desbordamientos de búfer y otros problemas que pueden estar presentes en la implementación del código nativo.
Impacto
A pesar de los impactos muy positivos, como la optimización del rendimiento y la ofuscación, el uso de código nativo en aplicaciones para Android puede tener impactos negativos en la seguridad. Los lenguajes de código nativo como C/C++ no tienen las funciones de seguridad de la memoria de Java/Kotlin, lo que los hace susceptibles a vulnerabilidades como desbordamientos de búfer, errores de uso después de liberar y otros problemas de corrupción de memoria, lo que provoca fallas o la ejecución de código arbitrario. Además, si existe una vulnerabilidad en el componente de código nativo, puede comprometer toda la aplicación, incluso si el resto está escrito de forma segura en Java.
Mitigaciones
Orientación para el desarrollo y la codificación
- Lineamientos de codificación segura: Para proyectos de C/C++, cumple con los estándares de codificación segura establecidos (p.ej., CERT, OWASP) para mitigar vulnerabilidades como desbordamientos de búfer, desbordamientos de números enteros y ataques de cadenas de formato. Prioriza bibliotecas como Abseil, conocidas por su calidad y seguridad. Siempre que sea posible, considera adoptar lenguajes seguros para la memoria como Rust, que ofrecen un rendimiento comparable a C/C++.
- Validación de entrada: Valida rigurosamente todos los datos de entrada recibidos de fuentes externas, incluidos los datos de entrada del usuario, los datos de red y los archivos, para evitar ataques de inyección y otras vulnerabilidades.
Protege las opciones de compilación
Las bibliotecas nativas que utilizan el formato ELF se pueden proteger contra una variedad de vulnerabilidades activando mecanismos de protección como la protección de pila (Canary), la reubicación de solo lectura (RELRO), la prevención de ejecución de datos (NX) y los ejecutables independientes de la posición (PIE). Las opciones de compilación del NDK de Android ya habilitan todas estas protecciones de forma predeterminada.
Para verificar la implementación de estos mecanismos de seguridad dentro de un objeto binario, puedes usar herramientas como hardening-check o pwntools.
Bash
$ pwn checksec --file path/to/libnativecode.so
Arch: aarch64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Verifica que las bibliotecas de terceros no sean vulnerables
Cuando elijas bibliotecas de terceros, prioriza el uso de aquellas con una sólida reputación en la comunidad de desarrollo. Recursos como el Índice
SDK de Google Play pueden ayudarte a identificar bibliotecas confiables y bien consideradas. Asegúrate
de mantener las bibliotecas actualizadas a las versiones más recientes y busca de forma proactiva
cualquier vulnerabilidad conocida relacionada con ellas usando recursos como las bases de datos
de Exploit-DB. Una búsqueda web con palabras clave como [library_name] vulnerability o [library_name] CVE puede revelar información de seguridad fundamental.
Recursos
- CWE-111: Uso directo de JNI no seguro
- Base de datos de exploits
- Verifica los objetos binarios para conocer las funciones de protección de seguridad
- Verifica la configuración de seguridad binaria con pwntools
- Endurecimiento de la seguridad de los objetos binarios de Linux
- Endurecimiento de objetos binarios ELF con reubicación de solo lectura (RELRO)
- Mecanismos de protección binaria de OWASP
- Estándares de codificación CERT de SEI
- Guía para desarrolladores de OWASP
- Índice SDK de Google Play
- NDK de Android
- Introducción a Rust de Android
- Abseil (bibliotecas comunes de C++)
- El vinculador aplica PIE