Skip to content

MASTG-TEST-0223: Stack Canaries Not Enabled

Visão Geral

Este caso de teste verifica se as bibliotecas nativas) do aplicativo são compiladas sem canários de pilha e, portanto, carecem de proteção contra estouro de pilha), uma técnica comum de mitigação contra ataques de buffer overflow.

  • As bibliotecas do NDK devem ter os canários de pilha habilitados, já que o compilador os ativa por padrão.
  • Outras bibliotecas personalizadas em C/C++ podem não ter os canários de pilha habilitados porque faltam as flags necessárias no compilador (-fstack-protector-strong ou -fstack-protector-all) ou os canários foram otimizados pelo compilador. Consulte a seção Avaliação) para mais detalhes.

Passos

  1. Extraia o conteúdo do aplicativo ( Explorando o Pacote do App).
  2. Execute Obtendo Recursos de Segurança Fornecidos pelo Compilador em cada biblioteca compartilhada e pesquise por "canary" ou a palavra-chave correspondente usada pela ferramenta selecionada.

Observação

A saída deve mostrar se os canários de pilha estão habilitados ou desabilitados.

Avaliação

O caso de teste falha se os canários de pilha estiverem desabilitados.

Os desenvolvedores precisam garantir que as flags -fstack-protector-strong ou -fstack-protector-all estejam definidas nas flags do compilador para todas as bibliotecas nativas. Isso é especialmente importante para bibliotecas personalizadas em C/C++ que não fazem parte do NDK.

Ao avaliar isso, observe que existem potenciais falsos positivos esperados para os quais o caso de teste deve ser considerado como aprovado. Para ter certeza nesses casos, é necessária uma revisão manual do código-fonte original e das flags de compilação utilizadas.

Os seguintes exemplos abrangem alguns dos casos de falsos positivos que podem ser encontrados:

Uso de Linguagens com Segurança de Memória

O framework Flutter não utiliza canários de pilha devido à forma como o Dart mitiga estouros de buffer.

Otimizações do Compilador

Às vezes, devido ao tamanho da biblioteca e às otimizações aplicadas pelo compilador, é possível que a biblioteca tenha sido originalmente compilada com canários de pilha, mas eles foram otimizados. Por exemplo, esse é o caso de alguns aplicativos React Native. Eles são construídos com -fstack-protector-strong, mas ao tentar buscar por stack_chk_fail dentro dos arquivos .so, ele não é encontrado.

  • Arquivos .so vazios: Alguns arquivos .so, como libruntimeexecutor.so ou libreact_render_debug.so, estão efetivamente vazios na versão de release e, portanto, não contêm símbolos. Mesmo que você tentasse compilar com -fstack-protector-all, ainda não seria possível ver a string stack_chk_fail, pois não há chamadas de método ali.
  • Falta de chamadas de buffer na pilha: Outros arquivos, como libreact_utils.so, libreact_config.so e libreact_debug.so, não estão vazios e contêm chamadas de método, mas esses métodos não contêm chamadas de buffer na pilha, então não há strings stack_chk_fail dentro deles.

Os desenvolvedores do React Native, nesse caso, declaram que não adicionarão -fstack-protector-all, pois, em sua opinião, consideram que isso adicionaria uma penalidade de desempenho sem ganho efetivo de segurança.