Categoria do OWASP: MASVS-CODE - Qualidade do código (link em inglês)
Visão geral
Os aplicativos Android podem aproveitar o código nativo escrito em linguagens como C e C++ para funcionalidades específicas. No entanto, quando um aplicativo usa a Java Native Interface (JNI) para interagir com esse código nativo, ele se expõe a vulnerabilidades como estouros de buffer e outros problemas que podem estar presentes na implementação do código nativo.
Impacto
Apesar dos impactos muito positivos, como otimização de desempenho e ofuscação, o uso de código nativo em aplicativos Android pode ter impactos negativos na segurança. Linguagens de código nativo, como C/C++, não têm os recursos de segurança de memória do Java/Kotlin, o que as torna suscetíveis a vulnerabilidades como estouros de buffer, erros de uso após liberação e outros problemas de corrupção de memória, levando a falhas ou execução de código arbitrário. Além disso, se houver uma vulnerabilidade no componente de código nativo, ela poderá comprometer todo o aplicativo, mesmo que o restante esteja escrito com segurança em Java.
Mitigações
Orientações sobre desenvolvimento e programação
- Diretrizes de programação segura: para projetos em C/C++, siga os padrões de programação segura estabelecidos (por exemplo, CERT, OWASP) para reduzir vulnerabilidades como estouros de buffer, estouros de números inteiros e ataques de string de formato. Priorize bibliotecas como Abseil, conhecidas pela qualidade e segurança. Sempre que possível, considere adotar linguagens seguras para a memória, como Rust, que oferecem desempenho comparável ao C/C++.
- Validação de entrada: valide rigorosamente todos os dados de entrada recebidos de fontes externas, incluindo entrada do usuário, dados de rede e arquivos, para evitar ataques de injeção e outras vulnerabilidades.
Reforçar as opções de compilação
As bibliotecas nativas que usam o formato ELF podem ser protegidas contra uma série de vulnerabilidades ativando mecanismos de proteção, como proteção de pilha (Canary), somente leitura de realocação (RELRO), prevenção de execução de dados (NX) e executáveis independentes de posição (PIE). As opções de compilação do Android NDK já ativam todas essas proteções por padrão.
Para verificar a implementação desses mecanismos de segurança em um binário, use ferramentas como hardening-check ou 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
Verificar se as bibliotecas de terceiros não estão vulneráveis
Ao escolher bibliotecas de terceiros, priorize o uso daquelas com uma reputação sólida na comunidade de desenvolvimento. Recursos como o índice de SDKs do Google Play podem ajudar você a identificar bibliotecas confiáveis e bem avaliadas. Mantenha as bibliotecas atualizadas com as versões mais recentes e procure proativamente vulnerabilidades conhecidas relacionadas a elas usando recursos como os bancos de dados do Exploit-DB. Uma pesquisa na Web usando palavras-chave como
[library_name] vulnerability ou [library_name] CVE pode revelar informações de segurança
críticas.
Recursos
- CWE-111: uso direto de JNI não seguro (link em inglês)
- Banco de dados de exploits
- Verificar se há recursos de reforço de segurança nos binários
- Verificar as configurações de segurança binária com o pwntools
- Reforço da proteção para a segurança de binários do Linux
- Reforço da proteção de binários ELF usando Relocation Read-Only (RELRO)
- Mecanismos de proteção binária do OWASP
- Padrões de programação do SEI CERT (em inglês)
- Guia do desenvolvedor do OWASP (link em inglês)
- SDK Index do Google Play
- Android NDK
- Introdução ao Rust no Android
- Abseil (bibliotecas comuns do C++)
- A PIA é aplicada pelo vinculador