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 estouro de buffer e outros problemas que podem estar presentes na implementação do código nativo.
Impacto
Apesar de impactos muito positivos, como otimização de desempenho e ofuscação, o uso de código nativo em apps 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 estouro de buffer, uso após a liberação e outros problemas de corrupção de memória, levando a falhas ou execução arbitrária de código. Além disso, se houver uma vulnerabilidade no componente de código nativo, ela poderá comprometer todo o aplicativo, mesmo que o restante seja gravado com segurança em Java.
Mitigações
Orientações sobre desenvolvimento e programação
- Diretrizes de codificação segura: para projetos C/C++, siga os padrões de codificação seguros estabelecidos (por exemplo, CERT, OWASP) para reduzir vulnerabilidades como estouro de buffer, estouro de inteiros e ataques de formatação de string. Priorize bibliotecas como o Abseil, conhecido 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 de forma rigorosa 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.
Aumentar a proteção das opções de compilação
As bibliotecas nativas que utilizam o formato ELF podem ser fortalecidas contra uma variedade de vulnerabilidades ativando mecanismos de proteção como proteção de pilha (Canary), realocação somente leitura (RELRO), prevenção de execução de dados (NX) e executáveis independentes de posição (PIE, na sigla em inglês). Por conveniência, 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, é possível usar 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 sã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 do
SDK do Google Play podem ajudar a identificar bibliotecas confiáveis e bem conceituadas. Mantenha
as bibliotecas atualizadas com as versões mais recentes e procure proativamente
qualquer vulnerabilidade conhecida relacionada 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
importantes de segurança.
Recursos
- CWE-111: uso direto de JNI não seguro
- Banco de dados de exploits
- Verificar binários para recursos de aumento da proteção
- Verificar as configurações de segurança binária com o pwntools
- Aumento da proteção para a segurança binária do Linux
- Reforço de binários ELF usando o modo somente leitura de realocação (RELRO)
- Mecanismos de proteção binária do OWASP (em inglês)
- Padrões de programação do CERT da SEI
- Guia do desenvolvedor do OWASP (em inglês)
- SDK Index do Google Play
- Android NDK
- Introdução ao Rust no Android (link em inglês)
- Abseil (bibliotecas comuns do C++)
- O PIE é aplicado pelo linker