Seu aplicativo Android como uma cena de crime!
Auditorias técnicas dos aplicativos iOS e Android tornaram-se uma parte integrante do nosso trabalho diário aqui na Karumi. Mesmo que ela pode parecer fácil, há vários detalhes de implementação para rever ao realizar a auditoria. Neste documento, vamos rever o que nós acreditamos que são as coisas mais importantes para verificar , separados por área técnica.
Sistema de Controle de Versão:
Se os engenheiros estão usando controle de versão, o sistema e processo usado define várias coisas sobre o processo de desenvolvimento de software.
-
Há um arquivo *ignore configurado corretamente para que arquivos de metadados e outros elementos dispensáveis não estão sob controle de versão?
-
Bibliotecas de terceiros estão versionadas no repositório ao contrário de configuradas como depedências externas?
-
Você usa mensagens suficientemente concisas e descritivas para cada commit?
-
É razoável o tamanho dos commits?
-
Todos os arquivos de um commit estão relacionados a mesma issue ou feature?
-
Você usa branches seguindo algum esquema de branching como “feature branch” ou “git-flow”?
-
Os nomes dos branches são suficientemente descritivos?
-
Você usa o pull request e code review antes do merge no master?
-
Você tem alguma orientação de análise de código para rever um PR?
-
Em média, há quantos comentários para cada PR?
-
Quantas pessoas revisam cada PR?
-
Quantos votos (+1) é necessário antes do merge?
-
Quem é o responsável por fechar o branch?
-
-
Você usa release branches para preparar cada lançamento?
-
Quanto tempo tem o seu processo de teste aberto?
-
Quantos consertos você contempla em sua release candidate antes de liberá-la?
-
Você consegue fazer o checkout do código usado para construir quaisquer versões publicadas de seu aplicativo?
-
Quantos hotfixes você lançou no ano passado?
-
Você está finalizando os commits no branch antes do merge no master/develop?
-
Os branches master/develop estão preparados para ser lançados a qualquer momento?
Ferramentas de Build:
Ser capaz de reproduzir o processo de compilação na máquina de cada desenvolvedor e qualquer outro sistema externo como integração contínua é fundamental.
-
Quantas bibliotecas você usa no projeto?
-
O projeto está dividido em diferentes módulos?
-
O projeto consome suas dependências através do Maven ou Gradle ou está usando jars locais?
-
O projeto está perigosamente se aproximando do limite de contagem do método dex? Já está além deste ponto?
-
Você usa bibliotecas que o seu projeto não necessita?
-
O projeto está usando multidex?
-
As depedências externas estão atualizadas?
-
Você está respeitando as licenças de cada bibliotecas de terceiros?
-
O projeto está usando alguma biblioteca de terceiros depreciada ou abandonada/sem manutenção?
-
O SDK mínimo é o exigido pela a descrição do produto?
-
O SDK alvo está atualizado?
-
Proguard ou qualquer outra ferramenta de ofuscação está habilitada e configurada corretamente?
-
As credenciais da keystore e Google Play Store estão armazenadas em a lugar seguro?
-
A aplicação está usando build types corretamente?
-
A aplicação está usando flavors corretamente?
-
O build type da release está configurado corretamente?
-
A opção de backup está ativada?
-
A opção de lint está ativada e está aprovado com sucesso?
-
Há uma ferramenta de análise configurada e executando sem erros?
-
Há algum checkstyle configurado e executado sem erros?
-
O application id e nome e código da versão estão configurados corretamente?
-
Você está usando alguma estrutura ou estrategia para versionamento de id?
-
Há ferramenta de integração contínua configurada?
-
Há processo de release automático?
Uso de recursos do Android:
Existe uma vasta gama de dispositivos no mundo Android, cada um com seu próprio tamanho de tela, recursos, etc. Você precisa ter cuidado dobrado e aproveitar algumas das ferramentas do Android para fornecer a melhor experiência possível para o usuário, independentemente do seu dispositivo .
-
Está faltando algum recurso de densities, flavors or build types?
-
Há suporte na aplicação para todas as densidades requeridas pelo a descrição do produto?
-
A aplicação está usando drawable/mipmap, fontes ou recursos vetoriais?
-
Está faltando alguma tradução?
-
O processo de tradução está automatizado?
-
Qual é a linguagem default para as traduções?
-
A aplicação usa alguma fonte customizada?
-
A aplicação usa valores configurados dentro do arquivo de String em resources?
-
A convenção de nomenclatura usada para definir os nomes dos recursos estão homogênia?
-
Os parametros configurados relacionados ao hardware do dispositivo está configurado corretamente?
-
Você está fornecendo suporte para tablets?
Uso de Layouts Android:
Como já dito antes, há uma ampla gama de dispositivos Android no mundo, cada um com tamanho de tela própria e densidade. Usar Layouts corretamente é fundamental
-
O número de camadas de layouts na aplicação pode produzir problemas de performance?
-
Você usa temas e estilos?
-
Você reusa layouts usando a tag “include”?
-
Você usa corretamente o tipo view group na implementação de layouts?
-
Os layouts estão configuradas para tamanhos de telas diferentes?
-
Há convenção de nomenclatura usada nos layouts e widgets?
-
As listas estão usando os componentes de ListView e RecyclerView?
-
Está usando Android Support Library corretamente?
Uso de Permissões:
Solicitar permissões define uma confiança entre os seus usuários e pode ajudar o seu app a integrar com outros serviços para proporcionar uma experiência agradável para seus usuários.
-
Todas as permissões solicitadas são realmente necessárias?
-
Há alguma permissão usada maliciosamente?
-
Está faltando alguma permissão?
-
O alvo da SDK usada é maior que 23 e a “permissões perigosas” solicitadas está usando a compatibilidade com o sistema de permissão?
-
As permissões estão sendo solicitadas no momento que será usada?
-
Há feedback para o usuário explicando a necessidade da permissão?
Issues de Segurança:
Como desenvolvedores, precisamos ser conscientes sobre a sua segurança do app, nós não queremos que os dados ou sessões dos usuários sejam roubados
-
O cliente HTTP está configurado para usar HTTPS?
-
O cliente HTTP está configurado para usar pinning de certificado e autenticação de mensagens com o HMAC?
-
Há persistência da aplicação de informação sensíveis do usuário? Onde?
-
Há persistência de informação na aplicação fora o armazenamento interno do sistema?
-
Há logs traces quando executar um novo build de release?
-
A aplicação tem código ofuscado?
-
A aplicação está expondo qualquer Android content provider, receiver ou serviço de outras aplicações?
-
O valor de “debuggable” da aplicação está desativado para release build?
Push Notifications:
Push é um grande mecanismo para manter nossos usuários informados sobre conteúdo relevante, a qualquer momento, mas é um problema mais complexo que parece à primeira vista.
-
O aplicativo usa uma biblioteca de terceiros para implementar o sistema de notificações push?
-
O sistema GCM está sendo usado para enviar informações para o aplicativo dentro das push notifications ou para mostrar apenas mensagens para o usuário?
-
Qual é o comportamento da aplicação quando uma push notification é recebida?
-
Qual é o comportamento da aplicação se a informação associada ao push notification não é a esperada?
-
As notificações são mostradas ao usuário usando a compatibilidade da API?
Performance:
Performance é critico. Ninguém quer usar um aplicativo ruim, lento em seu dispositivo de $ 400-600. Desempenho é $.
-
A aplicação tem qualquer vazamento de memória?
-
Há analisador de memória como “LeakCanary” configurado em build de desenvolvimento?
-
O modo Android Strict está ativado e configurado em build de desenvolvimento?
-
Qual é a aplicação de threading usada? Você está usando async tasks, intent services ou qualquer outra biblioteca de terceiros?
-
O número de thread executadas em background está causando problemas de performance?
-
Você usa algum scheduler policy ou apenas cria threads sob demanda?
-
Você tem em mente o modo Android Doze?
-
A aplicação tem eventos de listening relacionados a estado de rede ou qualquer evento repetitivo do sistema operacional?
-
A thread principal usada para executar tasks somente relacionadas a código de interface do usuário?
-
A aplicação está usando qualquer caching policy?
-
O cliente HTTP está configurado para usar timeout?
-
O cliente HTTP está configurado para usar o GZIP?
-
A UI da aplicação está executando 60 frames por segundo?
-
Existe alguma view personalizada implementada alocando muita memória ou executando threads caras na interface do usuário?
-
Você está testando seu aplicativo em dispositivos lower-end?
-
O scrolling de Recycler Views está lento?
-
A manipulação de imagens implementada está usando alguma biblioteca de terceiros ou você tem uma solução personalizada?
-
As imagens consumidas estão redimensionadas para o tamanho da tela ou é necessário baixar a imagem associada à tela do dispositivo?
-
O uso de memória está razoável?
-
Você está usando o modificador “static” do java corretamente?
-
Há qualquer tarefa relacionada com gestão de imagens com mais de uma imagem ao mesmo tempo?
- Is the stats tracking system working on a background thread configured with the correct priority?
-
Há sistema de rastreamento de estatísticas configurado e rodando em uma thread em background como prioridade?
- O código está otimizado no build de release?
Estrutura de Pacotes Java:
Uma boa estrutura de pacotes irá fazer com que seu código seja escalavel.
-
A divisão de código de pacotes usados é por features ou conceitos? Exemplo: Login vs Usuário?
-
Há visibilidade dos modificadores usado para esconder os detalhes das implementações dentro dos pacotes?
-
Os pacotes estão fora do root package?
-
As pastas de testes estão seguindos a mesma estrutura de pacotes implementada na pasta de código fonte?
-
As features estão organizadas e usando a mesma estrutura dos pacotes?
-
Há alguma classe fora do pacote correto?
-
A convenção de nomenclatura de pacotes está seguindo uma regra homogênia?
-
O nome do root package está relacionado ao nome da empresa??
Codestyle:
A base de código consistente em termos de estilo ajuda os nossos engenheiros para ler o código de uma maneira mais fácil. Suponhe-se, que um engenheiro deverua ler mais código do que escrever. Sendo assim, este é um conceito importante.
-
O codestyle está homogênio?
-
Você está usando hungarian notation?
-
Existe alguma ferramenta de checkstyle configurada e executando sem erros?
-
O código está seguindo o Java codestyle?
-
Você usa tabs ou espaços?
-
Os nomes das classes estão corretas?
-
Você está usando o prefixo “I” para interfaces ou “Impl” de sufixos para implementações?
-
Você está usando o nome correto das variaveis?
-
Você está usando o nome correto para os campos?
-
Você está usando o nome correto para os metódos?
-
Os atributos e metódos possuem modificadores de visibilidade usados corretamentes?
-
O código está em inglês?
-
Você está usando javadoc?
-
Você escreve comentários no seu código?
-
Você usa constantes ou enums para evitar literais duplicados?
Implementação Offline:
Prover uma experiência boa offline é um diferencial para suas aplicações.
-
A aplicação é usável quando não há conexão com internet?
-
Qual é o comportamento da aplicação quando a conexão com a internet está lenta?
-
Qual é o comportamento da aplicação quando um request foi barrado por uma falha de rede?
-
Modificações de dados na aplicação são sincronizadas com o backend da aplicação quando a conexão com a internet for restabelecida?
-
Há algum timeout configurado relacionado a conexões com internet?
-
Há algum HTTP caching policy configurado?
-
A sessão do usuário é renegociada automaticamente?
Arquitetura:
A arquitetura de aplicação do ponto de vista de código é uma das partes de uma auditoria que nos dá uma ideia mais clara sobre o aplicativo. Durante a revisão da arquitetura que será focado em conceitos relacionados com os S.O.L.I.D e os principios de Clean Code.
Implementação da Camada de Apresentação:
-
Há qualquer padrão relacionado com a implementação GUI utilizada na aplicação? Model View Presenter ou Model view ViewModel poderia ser dois dos padrões mais utilizados para desenvolver aplicações. Está implementado corretamente?
-
A implementação da camada de apresentação está associada a implementação de views?
-
A implementação de view está acoplada a implementação do model?
-
A camada de apresentação implementa requisitos de negócios?
-
A implementação de view utiliza as ferramentas do SDK do Android corretamente?
-
Você usa biblioteca de terceiros para simplificar a implementação das views?
-
As diferentes características estão implementadas em diferentes activities ou fragmentos?
-
O comportamento comum da UI é centralizado?
-
Você está usando views customizadas para reusar código de UI?
Implementação de Negócio:
-
Existe alguma camada de domínio ou a lógica é toda de negócio implementada dentro da camada de apresentação?
-
As regras de domínio e diferentes requisitos de aplicação expressa dentro das principais entidades de lógica de negócios?
-
A camada de negócio implementada está usando os principios de orientação objeto?
-
A camada de negócio está acoplada ao Android SDK ou qualquer outra biblioteca de terceiro?
-
A camada de negócio está acoplada a camada de apresentação?
-
O modelo de negócios é anêmico?
-
Você está usando modelo de negócios em excesso?
-
O código está basead em baixo acoplamento e alta coesão de componentes?
-
Há manipulação de erro implementada usando exceptions ou qualquer outro mecanismo de erro?
-
Há mapeamento de dados entre diferentes camadas?
-
Os componentes externos (como esquema de banco de dados ou json parsing) influenciam no padrão do modelo de negócios?
-
Os desenvolvedores estão abusando de herança?
-
Há código duplicado?
-
Biblioteca de injeção de depedência ou service locator configurados?
-
A complexidade de classe/metódo está muito alta?
Implementação da API do Cliente:
-
A implementação da API do cliente está acoplada ao SDK Android?
-
A implementação da API do cliente está vazando detalhes relacionados ao HTTP client ou a biblioteca usada para a implementação de camada de rede?
-
A implementação da API do cliente está enviando os headers corretamente?
-
Qual é o comportamento da API do cliente para diferentes respostas HTTP?
-
A implementação da API do cliente contempla mecanismos de autenticação?
-
O processo de renovação de sessão está implementado corretamente?
-
O JSON serializer suporta ofuscação?
-
A implementação da API do cliente está segregado em diferentes clientes?
Implementação de Armazenamento:
-
Onde a informação é armazenada?
-
Você está lendo/escrevendo dados armazenados usando transações?
-
O salvamento de informações sensíveis do usuário acontece de forma segura?
-
A camada de armazenamento está usando biblioteca de terceiros?
-
A camada de armazenamento está vazando detalhes da implementação?
-
As tabelas/esquemas de armazenamento está modelados corretamente?
-
As consultas enviadas ao armazenamento estão otimizadas?
-
As APIs de persistência do Android SDK estão armazenando os dados no local correto? E quanto aos dados do banco de dados, preferências ou os pequenos dados de shared preferences e os arquivos em disco?
Testes:
-
A aplicação tem testes?
-
A aplicação é testável?
-
A cobertura de testes da aplicação é baseada em diferentes estrategias de teste (unidade/integração/end-to-end)?
-
Os testes possuem nomenclatura corretamente?
-
Os testes possuem escopo corretamente?
-
Há testes sem especificação?
-
O tempo de execução de testes é razoável?
-
A cobertura de testes código é baixa?
-
Existe algum teste ignorado?
-
Existe algum flaky tests?
-
Você usa frameworks de testes atualizados?
-
Existem algum teste sem asserts?
-
Os testes escritos pelos mesmos desenvolvedores implementam o código de produção?
-
Você tem uma equipe de QA para testes manuais?
-
Você tem uma equipe de QA automatizando parte dos testes?
-
Você usa algum sistema de integração contínua?
-
Você usa builders, factories ou mothers para reduzir o esforço necessário para criar algumas entidades que são necessários apenas para testes?
-
Os tests assertions estão escritos corretamente?
-
Você executa mais de um assert de lógica por teste?
-
Você tem diferentes conjuntos de testes relacionados com o mesmo projeto?
-
Você está usando diferentes abordagens de teste para testar diferentes partes da aplicação?
-
Você está usando o monkeyrunner?
-
Você está seguindo alguma metodologia de TDD ou BDD?
-
Você usa java para escrever os casos de testes?
Com base nesta lista relacionando diferentes temas, podemos afirmar a qualidade do aplicativo. Há outros pontos que também é necessário revisar mas esta lista contém os mais importantes. Você está dando as respostas corretas para todas estas perguntas?
Por Pedro Vicente Gómez Sánchez.