Teste de Segurança de Aplicações Móveis¶
Nas seções a seguir, forneceremos uma breve visão geral dos princípios gerais de teste de segurança e terminologia-chave. Os conceitos apresentados são em grande parte idênticos aos encontrados em outros tipos de teste de penetração, portanto, se você é um testador experiente, pode estar familiarizado com parte do conteúdo.
Ao longo do guia, usamos "teste de segurança de aplicações móveis" como um termo abrangente para nos referirmos à avaliação da segurança de aplicações móveis por meio de análise estática e dinâmica. Termos como "teste de penetração de aplicações móveis" e "revisão de segurança de aplicações móveis" são usados de forma um tanto inconsistente na indústria de segurança, mas esses termos se referem basicamente à mesma coisa. Um teste de segurança de aplicação móvel geralmente faz parte de uma avaliação de segurança maior ou teste de penetração que abrange a arquitetura cliente-servidor e as APIs do lado do servidor usadas pela aplicação móvel.
Neste guia, cobrimos o teste de segurança de aplicações móveis em dois contextos. O primeiro é o teste de segurança "clássico" realizado próximo ao final do ciclo de vida de desenvolvimento. Nesse contexto, o testador acessa uma versão quase finalizada ou pronta para produção do aplicativo, identifica problemas de segurança e escreve um relatório (geralmente devastador). O outro contexto é caracterizado pela implementação de requisitos e pela automação de testes de segurança desde o início do ciclo de vida de desenvolvimento de software em diante. Os mesmos requisitos básicos e casos de teste se aplicam a ambos os contextos, mas o método de alto nível e o nível de interação com o cliente diferem.
Princípios de Teste¶
Teste White-box versus Teste Black-box¶
Vamos começar definindo os conceitos:
- Teste Black-box é realizado sem que o testador tenha qualquer informação sobre o aplicativo sendo testado. Esse processo às vezes é chamado de "teste de conhecimento zero". O principal objetivo deste teste é permitir que o testador se comporte como um atacante real, no sentido de explorar possíveis usos para informações publicamente disponíveis e descobríveis.
- Teste White-box (às vezes chamado de "teste de conhecimento completo") é o oposto total do teste black-box, no sentido de que o testador tem conhecimento completo do aplicativo. O conhecimento pode abranger código-fonte, documentação e diagramas. Essa abordagem permite testes muito mais rápidos do que o teste black-box devido à sua transparência e, com o conhecimento adicional adquirido, um testador pode construir casos de teste muito mais sofisticados e granulares.
- Teste Gray-box é todo teste que se situa entre os dois tipos mencionados anteriormente: algumas informações são fornecidas ao testador (normalmente apenas credenciais), e outras informações devem ser descobertas. Esse tipo de teste é um compromisso interessante em termos de número de casos de teste, custo, velocidade e escopo do teste. O teste gray-box é o tipo mais comum de teste na indústria de segurança.
Recomendamos fortemente que você solicite o código-fonte para que possa utilizar o tempo de teste da forma mais eficiente possível. O acesso do testador ao código obviamente não simula um ataque externo, mas simplifica a identificação de vulnerabilidades ao permitir que o testador verifique cada anomalia identificada ou comportamento suspeito no nível do código. Um teste white-box é o caminho a seguir se o aplicativo não foi testado anteriormente.
Embora a descompilação no Android seja direta, o código-fonte pode estar ofuscado, e a desofuscação consumirá tempo. Restrições de tempo são, portanto, outro motivo para o testador ter acesso ao código-fonte.
Análise de Vulnerabilidades¶
A análise de vulnerabilidades geralmente é o processo de procurar por vulnerabilidades em um aplicativo. Embora isso possa ser feito manualmente, scanners automatizados geralmente são usados para identificar as principais vulnerabilidades. Análise estática (static analysis) e análise dinâmica (dynamic analysis) são tipos de análise de vulnerabilidades.
Análise Estática versus Dinâmica¶
O Static Application Security Testing (SAST) envolve examinar os componentes de um aplicativo sem executá-los, por meio da análise do código-fonte de forma manual ou automática.
A OWASP fornece informações sobre Static Code Analysis que podem ajudar você a entender técnicas, pontos fortes, fracos e limitações.
O Dynamic Application Security Testing (DAST) envolve examinar o aplicativo durante a execução. Esse tipo de análise pode ser manual ou automático. Geralmente, ele não fornece as informações que a análise estática oferece, mas é uma boa maneira de detectar elementos interessantes (ativos, funcionalidades, pontos de entrada, etc.) do ponto de vista do usuário.
Agora que definimos análise estática e dinâmica, vamos aprofundar.
Análise Estática¶
Durante a análise estática, o código-fonte do aplicativo móvel é revisado para garantir a implementação adequada de controles de segurança. Na maioria dos casos, é utilizada uma abordagem híbrida automática/manual. As verificações automáticas identificam os problemas mais evidentes, e o testador humano pode explorar a base de código com contextos de uso específicos em mente.
Revisão Manual de Código¶
Um testador realiza a revisão manual de código analisando manualmente o código-fonte do aplicativo móvel em busca de vulnerabilidades de segurança. Os métodos variam desde uma busca básica por palavras-chave por meio do comando 'grep' até uma análise linha por linha do código-fonte. As IDEs (Ambientes de Desenvolvimento Integrado) geralmente fornecem funções básicas de revisão de código e podem ser estendidas com várias ferramentas.
Uma abordagem comum para a análise manual de código envolve a identificação de indicadores-chave de vulnerabilidades de segurança por meio da busca por determinadas APIs e palavras-chave, como chamadas de métodos relacionados a banco de dados, como "executeStatement" ou "executeQuery". Códigos que contêm essas strings são um bom ponto de partida para a análise manual.
Em contraste com a análise automática de código, a revisão manual é muito eficaz para identificar vulnerabilidades na lógica de negócios, violações de padrões e falhas de design, especialmente quando o código é tecnicamente seguro, mas logicamente falho. Tais cenários dificilmente seriam detectados por qualquer ferramenta de análise automática de código.
Uma revisão manual de código exige um revisor especializado que seja proficiente tanto na linguagem quanto nos frameworks utilizados para o aplicativo móvel. Uma revisão completa de código pode ser um processo lento, tedioso e demorado para o revisor, especialmente em bases de código grandes com muitas dependências.
Análise Automatizada de Código-Fonte¶
Ferramentas de análise automatizada podem ser usadas para acelerar o processo de revisão do Teste Estático de Segurança de Aplicações (SAST). Elas verificam o código-fonte quanto à conformidade com um conjunto predefinido de regras ou melhores práticas do setor, normalmente exibindo uma lista de achados, avisos e sinalizações para todas as violações detectadas. Algumas ferramentas de análise estática executam apenas contra o aplicativo compilado, outras precisam receber o código-fonte original, e algumas funcionam como plugins de análise em tempo real no Ambiente de Desenvolvimento Integrado (IDE).
Embora algumas ferramentas de análise estática de código incorporem muitas informações sobre as regras e semânticas necessárias para analisar aplicativos móveis, elas podem produzir muitos falsos positivos, especialmente se não estiverem configuradas para o ambiente de destino. Portanto, um profissional de segurança deve sempre revisar os resultados.
Análise Dinâmica¶
O foco do DAST é o teste e a avaliação de aplicativos por meio de sua execução em tempo real. O principal objetivo da análise dinâmica é encontrar vulnerabilidades de segurança ou pontos fracos em um programa durante sua execução. A análise dinâmica é conduzida tanto na camada da plataforma móvel quanto contra os serviços e APIs de backend, onde os padrões de requisição e resposta do aplicativo móvel podem ser analisados.
A análise dinâmica é geralmente utilizada para verificar se os mecanismos de segurança oferecem proteção suficiente contra os tipos mais prevalentes de ataques, como divulgação de dados em trânsito, problemas de autenticação e autorização, e erros de configuração do servidor.
Evitando Falsos Positivos¶
Ferramentas de Varredura Automatizada¶
A falta de sensibilidade às particularidades do contexto do aplicativo é um desafio das ferramentas de teste automatizado. Essas ferramentas podem identificar problemas potenciais que são irrelevantes. Tais resultados são chamados de "falsos positivos".
Por exemplo, testadores de segurança frequentemente reportam vulnerabilidades que são exploráveis em um navegador web, mas não são relevantes para o aplicativo móvel. Esse falso positivo ocorre porque as ferramentas automatizadas usadas para escanear o serviço backend são baseadas em aplicações web tradicionais para navegadores. Problemas como CSRF (Cross-site Request Forgery) e Cross-Site Scripting (XSS) são reportados de acordo.
Vamos tomar o CSRF como exemplo. Um ataque CSRF bem-sucedido requer o seguinte:
- A capacidade de induzir o usuário logado a abrir um link malicioso no navegador web usado para acessar o site vulnerável.
- O cliente (navegador) deve adicionar automaticamente o cookie de sessão ou outro token de autenticação à requisição.
Aplicativos móveis não atendem a esses requisitos: mesmo que WebViews e gerenciamento de sessão baseado em cookie sejam usados, qualquer link malicioso clicado pelo usuário é aberto no navegador padrão, que possui um armazenamento de cookies separado.
Cross-Site Scripting (XSS) armazenado pode ser um problema se o aplicativo incluir WebViews, e pode até levar à execução de comandos se o aplicativo exportar interfaces JavaScript. No entanto, Cross-Site Scripting refletido raramente é um problema pelo motivo mencionado acima (embora seja discutível se eles deveriam existir, escapar a saída é simplesmente uma prática recomendada).
Em qualquer caso, considere os cenários de exploração ao realizar a avaliação de risco; não confie cegamente na saída da sua ferramenta de varredura.
Teste de Penetração (também conhecido como Pentesting)¶
A abordagem clássica envolve testes de segurança abrangentes da versão final ou quase final do aplicativo, por exemplo, a versão disponível ao final do processo de desenvolvimento. Para testes realizados ao final do processo de desenvolvimento, recomendamos o Mobile App Security Verification Standard (MASVS) e a lista de verificação associada como base para os testes. Um teste de segurança típico é estruturado da seguinte forma:
- Preparação - definição do escopo dos testes de segurança, incluindo a identificação dos controles de segurança aplicáveis, os objetivos de teste da organização e os dados sensíveis. De forma mais geral, a preparação inclui toda a sincronização com o cliente, bem como a proteção legal do testador (que frequentemente é um terceiro). Lembre-se: atacar um sistema sem autorização por escrito é ilegal em muitas partes do mundo!
- Coleta de Informações - análise do contexto ambiental e arquitetônico do aplicativo para obter uma compreensão contextual geral.
- Mapeamento do Aplicativo - com base nas informações das fases anteriores; pode ser complementado por varredura automatizada e exploração manual do aplicativo. O mapeamento fornece uma compreensão detalhada do aplicativo, seus pontos de entrada, os dados que ele mantém e as principais vulnerabilidades potenciais. Essas vulnerabilidades podem então ser classificadas de acordo com o dano que sua exploração causaria, para que o testador de segurança possa priorizá-las. Esta fase inclui a criação de casos de teste que podem ser utilizados durante a execução dos testes.
- Exploração - nesta fase, o testador de segurança tenta penetrar no aplicativo explorando as vulnerabilidades identificadas durante a fase anterior. Esta fase é necessária para determinar se as vulnerabilidades são reais e verdadeiros positivos.
- Relatório - nesta fase, essencial para o cliente, o testador de segurança reporta as vulnerabilidades. Isso inclui o processo de exploração em detalhes, classifica o tipo de vulnerabilidade, documenta o risco se um invasor conseguir comprometer o alvo e descreve quais dados o testador conseguiu acessar ilegitimamente.
Preparação¶
O nível de segurança no qual o aplicativo será testado deve ser decidido antes dos testes. Os requisitos de segurança devem ser definidos no início do projeto. Diferentes organizações possuem necessidades de segurança distintas e recursos disponíveis para investir em atividades de teste. Embora os testes do perfil MAS-L1 sejam aplicáveis a todos os aplicativos móveis, percorrer todos os testes MAS-L1 e MAS-L2 com as partes interessadas técnicas e de negócios é uma boa maneira de decidir sobre um nível de cobertura de teste.
As organizações podem ter obrigações regulatórias e legais diferentes em determinados territórios. Mesmo que um aplicativo não lide com dados sensíveis, alguns testes MAS-L2 podem ser relevantes (devido a regulamentações do setor ou leis locais). Por exemplo, a autenticação de dois fatores (2FA) pode ser obrigatória para um aplicativo financeiro e exigida pelo banco central de um país e/ou autoridades reguladoras financeiras.
Os objetivos/controles de segurança definidos anteriormente no processo de desenvolvimento também podem ser revisados durante a discussão com as partes interessadas. Alguns controles podem estar em conformidade com os perfis MAS, mas outros podem ser específicos da organização ou do aplicativo.
Todas as partes envolvidas devem concordar com as decisões e o escopo definidos na lista de verificação, pois estes definirão a base de referência para todos os testes de segurança.
Coordenação com o Cliente¶
Configurar um ambiente de teste funcional pode ser uma tarefa desafiadora. Por exemplo, restrições nos pontos de acesso sem fio corporativos e nas redes podem impedir a análise dinâmica realizada nas instalações do cliente. Políticas da empresa podem proibir o uso de dispositivos com root ou ferramentas de teste de rede (de hardware e software) dentro das redes corporativas. Aplicativos que implementam detecção de root e outras contramedidas de engenharia reversa podem aumentar significativamente o trabalho necessário para análises posteriores.
O teste de segurança envolve muitas tarefas invasivas, incluindo monitoramento e manipulação do tráfego de rede do aplicativo móvel, inspeção dos arquivos de dados do app e instrumentação de chamadas de API. Controles de segurança, como certificate pinning e detecção de root, podem impedir essas tarefas e reduzir drasticamente a velocidade dos testes.
Para superar esses obstáculos, você pode solicitar duas variantes de build do aplicativo à equipe de desenvolvimento. Uma variante deve ser uma build de release para que você possa determinar se os controles implementados estão funcionando corretamente e não podem ser contornados facilmente. A segunda variante deve ser uma debug build na qual certos controles de segurança foram desativados. Testar duas builds diferentes é a maneira mais eficiente de cobrir todos os casos de teste.
Dependendo do escopo do contrato, essa abordagem pode não ser possível. Solicitar tanto builds de produção quanto de debug para um teste white-box ajudará você a concluir todos os casos de teste e declarar claramente a maturidade de segurança do aplicativo. O cliente pode preferir que testes black-box sejam focados no aplicativo de produção e na avaliação da eficácia de seus controles de segurança.
O escopo de ambos os tipos de teste deve ser discutido durante a fase de preparação. Por exemplo, se os controles de segurança devem ser ajustados deve ser decidido antes do teste. Tópicos adicionais são discutidos abaixo.
Identificação de Dados Sensíveis¶
As classificações de informações sensíveis variam conforme o setor e o país. Além disso, as organizações podem adotar uma visão restritiva sobre dados sensíveis, podendo possuir uma política de classificação de dados que defina claramente o que constitui informação sensível.
Existem três estados gerais a partir dos quais os dados podem ser acessíveis:
- At rest (em repouso) – os dados estão armazenados em um arquivo ou repositório de dados
- In use (em uso) – um aplicativo carregou os dados em seu espaço de endereçamento
- In transit (em trânsito) – os dados foram trocados entre o aplicativo móvel e um endpoint ou processos consumidores no dispositivo, por exemplo, durante IPC (Comunicação Entre Processos)
O nível de escrutínio apropriado para cada estado pode depender da importância dos dados e da probabilidade de serem acessados. Por exemplo, dados mantidos na memória do aplicativo podem ser mais vulneráveis do que dados em servidores web a acessos por meio de despejos de memória (core dumps), pois é mais provável que atacantes tenham acesso físico a dispositivos móveis do que a servidores web.
Quando não houver uma política de classificação de dados disponível, utilize a seguinte lista de informações geralmente consideradas sensíveis:
- informações de autenticação do usuário (credenciais, PINs, etc.)
- Informações Pessoalmente Identificáveis (PII) que possam ser usadas para roubo de identidade: números de previdência social, números de cartão de crédito, números de conta bancária, informações de saúde
- identificadores de dispositivo que possam identificar uma pessoa
- dados altamente sensíveis cujo comprometimento levaria a danos reputacionais e/ou custos financeiros
- quaisquer dados cuja proteção seja uma obrigação legal
- quaisquer dados técnicos gerados pelo aplicativo (ou seus sistemas relacionados) e usados para proteger outros dados ou o próprio sistema (por exemplo, chaves de criptografia)
Uma definição de "dados sensíveis" deve ser estabelecida antes do início dos testes, pois detectar vazamento de dados sensíveis sem uma definição pode ser impossível.
Identificação de Contextos Relevantes para Segurança no Código¶
Ao desenvolver uma aplicação móvel, é crucial identificar e tratar com precisão os contextos relevantes para segurança dentro da base de código. Esses contextos normalmente envolvem operações como autenticação, criptografia e autorização, que frequentemente são alvo de ataques de segurança. A implementação incorreta de funções criptográficas nessas áreas pode levar a vulnerabilidades de segurança significativas.
Distinguir adequadamente os contextos relevantes para segurança ajuda a minimizar falsos positivos durante os testes de segurança. Falsos positivos podem desviar a atenção de problemas reais e desperdiçar recursos valiosos. Aqui estão alguns cenários comuns:
-
Geração de Números Aleatórios: O uso de geradores de números aleatórios previsíveis pode ser uma falha de segurança grave em contextos como autenticação ou geração de chaves de criptografia. No entanto, nem todos os usos de números aleatórios são sensíveis à segurança. Por exemplo, usar um gerador de números aleatórios menos robusto para fins não relacionados à segurança, como embaralhar uma lista de itens em um jogo, geralmente é aceitável.
-
Hashing: O hashing é frequentemente usado na segurança para armazenar senhas ou garantir a integridade dos dados. No entanto, aplicar hashing a um valor não sensível, como a resolução de tela de um dispositivo para análise, não é uma preocupação de segurança.
-
Criptografia vs. Codificação: Um equívoco comum é confundir codificação (como Base64) com criptografia. A codificação Base64 não é um método seguro para proteger dados sensíveis, pois é facilmente reversível. É crucial reconhecer quando os dados exigem criptografia real (para confidencialidade) versus quando estão sendo codificados por motivos de compatibilidade ou formatação (como codificar dados binários em formato de texto para transmissão). Interpretar erroneamente a codificação como uma medida de segurança pode levar a negligenciar a necessidade real de criptografia para dados sensíveis.
-
Armazenamento de Tokens de API: Armazenar tokens ou chaves de API em texto simples dentro do código do aplicativo ou em locais inseguros (como SharedPreferences no Android ou UserDefaults no iOS) é um erro de segurança comum. No entanto, se o token for para uma API pública não sensível e somente leitura, isso pode não representar um risco de segurança. Em contraste, armazenar um token para uma API sensível ou com acesso de escrita, onde o armazenamento inadequado seria uma preocupação de segurança significativa.
Coleta de Inteligência¶
A coleta de inteligência envolve a reunião de informações sobre a arquitetura do app, os casos de uso de negócio atendidos pelo app e o contexto no qual o app opera. Tais informações podem ser classificadas como "ambientais" ou "arquiteturais".
Informações do Ambiente¶
As informações do ambiente incluem:
- Os objetivos da organização para o aplicativo. A funcionalidade molda a interação dos usuários com o aplicativo e pode tornar algumas superfícies mais propensas a serem alvo de atacantes do que outras.
- O setor relevante. Diferentes setores podem ter perfis de risco distintos.
- Partes interessadas e investidores; compreender quem tem interesse e é responsável pelo aplicativo.
- Processos internos, fluxos de trabalho e estruturas organizacionais. Processos e fluxos de trabalho internos específicos da organização podem criar oportunidades para vulnerabilidades de lógica de negócio.
Informações Arquiteturais¶
As informações arquiteturais incluem:
- O aplicativo móvel: Como o app acessa dados e os gerencia em processo, como se comunica com outros recursos e gerencia sessões de usuário, e se detecta que está sendo executado em dispositivos com jailbreak ou root e reage a essas situações.
- O Sistema Operacional: Os sistemas operacionais e versões do SO em que o app é executado (incluindo restrições de versão do Android ou iOS), se o app deve ser executado em dispositivos com controles de Mobile Device Management (MDM) e vulnerabilidades relevantes do SO.
- Rede: Uso de protocolos de transporte seguros (por exemplo, TLS), uso de chaves fortes e algoritmos criptográficos (por exemplo, SHA-2) para garantir a criptografia do tráfego de rede, uso de certificate pinning para verificar o endpoint, etc.
- Serviços Remotos: Os serviços remotos consumidos pelo app e se a comprometimento deles poderia comprometer o cliente.
Mapeamento da Aplicação¶
Uma vez que o testador de segurança possui informações sobre o aplicativo e seu contexto, o próximo passo é mapear a estrutura e o conteúdo do app, por exemplo, identificando seus pontos de entrada, funcionalidades e dados.
Quando o teste de penetração é realizado sob o paradigma de caixa branca ou caixa cinza, quaisquer documentos do interior do projeto (diagramas de arquitetura, especificações funcionais, código, etc.) podem facilitar bastante o processo. Se o código-fonte estiver disponível, o uso de ferramentas SAST pode revelar informações valiosas sobre vulnerabilidades (por exemplo, SQL Injection).
Ferramentas DAST podem apoiar testes de caixa preta e escanear automaticamente o aplicativo: enquanto um testador precisará de horas ou dias, um scanner pode realizar a mesma tarefa em alguns minutos. No entanto, é importante lembrar que ferramentas automáticas têm limitações e encontrarão apenas o que foram programadas para encontrar. Portanto, a análise humana pode ser necessária para complementar os resultados das ferramentas automáticas (a intuição é frequentemente fundamental para testes de segurança).
A Modelagem de Ameaças é um artefato importante: documentos provenientes de workshops geralmente apoiam bastante a identificação de grande parte das informações que um testador de segurança precisa (pontos de entrada, ativos, vulnerabilidades, gravidade, etc.). É altamente recomendável que os testadores discutam a disponibilidade de tais documentos com o cliente. A modelagem de ameaças deve ser uma parte fundamental do ciclo de vida de desenvolvimento de software. Ela geralmente ocorre nas fases iniciais de um projeto.
As diretrizes de modelagem de ameaças definidas pela OWASP são geralmente aplicáveis a aplicativos móveis.
Exploração¶
Infelizmente, limitações de tempo ou financeiras restringem muitos pentests ao mapeamento de aplicações por meio de scanners automatizados (para análise de vulnerabilidades, por exemplo). Embora as vulnerabilidades identificadas durante a fase anterior possam ser interessantes, sua relevância deve ser confirmada com base em cinco eixos:
- Potencial de dano — o prejuízo que pode resultar da exploração da vulnerabilidade
- Reprodutibilidade — a facilidade de reproduzir o ataque
- Explorabilidade — a facilidade de executar o ataque
- Usuários afetados — o número de usuários impactados pelo ataque
- Detectabilidade — a facilidade de descobrir a vulnerabilidade
Contra todas as expectativas, algumas vulnerabilidades podem não ser exploráveis e podem levar a comprometimentos menores, se é que levam a algum. Outras vulnerabilidades podem parecer inofensivas à primeira vista, mas se revelam muito perigosas sob condições realistas de teste. Os testadores que percorrem cuidadosamente a fase de exploração apoiam o pentest ao caracterizar vulnerabilidades e seus efeitos.
Relatório¶
As descobertas do testador de segurança serão valiosas para o cliente apenas se estiverem claramente documentadas. Um bom relatório de pentest deve incluir informações como, mas não se limitando a:
- um resumo executivo
- uma descrição do escopo e contexto (por exemplo, sistemas direcionados)
- métodos utilizados
- fontes de informação (fornecidas pelo cliente ou descobertas durante o pentest)
- descobertas priorizadas (por exemplo, vulnerabilidades estruturadas pela classificação DREAD)
- descobertas detalhadas
- recomendações para corrigir cada defeito
Muitos modelos de relatório de pentest estão disponíveis na Internet: o Google é seu amigo!
Testes de Segurança e o SDLC¶
Embora os princípios dos testes de segurança não tenham mudado fundamentalmente na história recente, as técnicas de desenvolvimento de software mudaram drasticamente. Enquanto a adoção generalizada de práticas Agile acelerava o desenvolvimento de software, os testadores de segurança tiveram que se tornar mais rápidos e ágeis, continuando a entregar software confiável.
A seção a seguir foca nessa evolução e descreve os testes de segurança contemporâneos.
Teste de Segurança durante o Ciclo de Vida do Desenvolvimento de Software¶
O desenvolvimento de software não é muito antigo, afinal de contas, então é fácil observar o fim do desenvolvimento sem uma estrutura. Todos nós já experimentamos a necessidade de um conjunto mínimo de regras para controlar o trabalho à medida que o código-fonte cresce.
No passado, as metodologias "Waterfall" eram as mais adotadas: o desenvolvimento prosseguia por etapas que tinham uma sequência predefinida. Limitada a uma única etapa, a capacidade de retroceder era uma desvantagem séria das metodologias Waterfall. Embora tenham características positivas importantes (fornecer estrutura, ajudar testadores a esclarecer onde o esforço é necessário, serem claras e fáceis de entender, etc.), também têm aspectos negativos (criar silos, serem lentas, equipes especializadas, etc.).
À medida que o desenvolvimento de software amadureceu, a competição aumentou e os desenvolvedores precisaram reagir mais rapidamente às mudanças do mercado enquanto criavam produtos de software com orçamentos menores. A ideia de menos estrutura tornou-se popular, e equipes menores colaboraram, quebrando silos em toda a organização. O conceito "Ágil" nasceu (Scrum, XP e RAD são exemplos bem conhecidos de implementações Ágeis); ele permitiu que equipes mais autônomas trabalhassem juntas mais rapidamente.
A segurança originalmente não era uma parte integral do desenvolvimento de software. Era uma reflexão tardia, realizada no nível de rede por equipes de operação que tinham que compensar a segurança deficiente do software! Embora a segurança não integrada fosse possível quando os programas de software estavam localizados dentro de um perímetro, o conceito tornou-se obsoleto à medida que novos tipos de consumo de software surgiram com tecnologias web, móveis e IoT. Hoje em dia, a segurança deve ser integrada dentro do software, porque compensar vulnerabilidades geralmente é muito difícil.
"SDLC" será usado alternadamente com "Secure SDLC" na seção a seguir para ajudá-lo a internalizar a ideia de que a segurança é parte dos processos de desenvolvimento de software. No mesmo espírito, usamos o nome DevSecOps para enfatizar o fato de que a segurança é parte do DevOps.
Visão Geral do SDLC¶
Descrição Geral do SDLC¶
Os SDLCs sempre consistem nas mesmas etapas (o processo geral é sequencial no paradigma Waterfall e iterativo no paradigma Agile):
- Realize uma avaliação de riscos para o aplicativo e seus componentes para identificar seus perfis de risco. Esses perfis de risco normalmente dependem do apetite de risco da organização e dos requisitos regulatórios aplicáveis. A avaliação de riscos também se baseia em fatores, incluindo se o aplicativo é acessível via Internet e o tipo de dados que o aplicativo processa e armazena. Todos os tipos de riscos devem ser considerados: financeiros, de marketing, industriais, etc. Políticas de classificação de dados especificam quais dados são sensíveis e como devem ser protegidos.
- Requisitos de Segurança são determinados no início de um projeto ou ciclo de desenvolvimento, quando os requisitos funcionais estão sendo coletados. Casos de Abuso são adicionados à medida que os casos de uso são criados. As equipes (incluindo equipes de desenvolvimento) podem receber treinamento em segurança (como Codificação Segura) se necessário. Você pode usar o OWASP MASVS e o OWASP MASWE para determinar os requisitos de segurança de aplicativos móveis com base na fase de avaliação de riscos. A revisão iterativa dos requisitos quando funcionalidades e classes de dados são adicionadas é comum, especialmente em projetos Agile.
- Modelagem de Ameaças, que basicamente é a identificação, enumeração, priorização e tratamento inicial de ameaças, é um artefato fundamental que deve ser realizado conforme o desenvolvimento e o design da arquitetura progridem. A Arquitetura de Segurança, um fator da Modelagem de Ameaças, pode ser refinada (tanto para aspectos de software quanto de hardware) após a fase de Modelagem de Ameaças. Regras de Codificação Segura são estabelecidas e a lista de Ferramentas de Segurança que serão usadas é criada. A estratégia para Testes de Segurança é esclarecida.
- Todos os requisitos de segurança e considerações de design devem ser armazenados no sistema de Gerenciamento do Ciclo de Vida de Aplicativos (ALM) (também conhecido como rastreador de problemas) que a equipe de desenvolvimento/operações usa para garantir a integração estreita dos requisitos de segurança no fluxo de trabalho de desenvolvimento. Os requisitos de segurança devem conter trechos de código-fonte relevantes para que os desenvolvedores possam consultá-los rapidamente. Criar um repositório dedicado que esteja sob controle de versão e contenha apenas esses trechos de código é uma estratégia de codificação segura mais benéfica do que a abordagem tradicional (armazenar as diretrizes em documentos do Word ou PDFs).
- Desenvolva o software com segurança. Para aumentar a segurança do código, você deve concluir atividades como Revisões de Código de Segurança, Testes Estáticos de Segurança de Aplicativos e Testes de Unidade de Segurança. Embora existam análogos de qualidade dessas atividades de segurança, a mesma lógica deve ser aplicada à segurança, por exemplo, revisar, analisar e testar o código em busca de defeitos de segurança (como validação de entrada ausente, falha em liberar todos os recursos, etc.).
- Em seguida, vem o tão aguardado teste do candidato a lançamento: Testes de Penetração ("Pentests") manuais e automatizados. Testes Dinâmicos de Segurança de Aplicativos geralmente também são realizados durante esta fase.
- Após o software ter sido Credenciado durante a Aceitação por todas as partes interessadas, ele pode ser transferido com segurança para as equipes de Operação e colocado em Produção.
- A última fase, muitas vezes negligenciada, é a Desativação segura do software após o fim de seu uso.
A imagem abaixo ilustra todas as fases e artefatos:

Nota: O texto na imagem permanece em inglês.
Com base no perfil de risco geral do projeto, você pode simplificar (ou até mesmo pular) alguns artefatos e adicionar outros (aprovações intermediárias formais, documentação formal de certos pontos, etc.). Lembre-se sempre de duas coisas: um SDLC tem como objetivo reduzir os riscos associados ao desenvolvimento de software e é uma estrutura que ajuda você a estabelecer controles para esse fim. Esta é uma descrição genérica do SDLC; sempre adapte essa estrutura aos seus projetos.
Definindo uma Estratégia de Teste¶
Estratégias de teste especificam os testes que serão realizados durante o SDLC, bem como a frequência dos testes. As estratégias de teste são utilizadas para garantir que o produto final de software atenda aos objetivos de segurança, que geralmente são determinados pelas equipes jurídicas/marketing/corporativas dos clientes. A estratégia de teste geralmente é criada durante a fase de Design Seguro, após os riscos terem sido esclarecidos (durante a fase de Iniciação) e antes do início do desenvolvimento do código (fase de Implementação Segura). A estratégia requer contribuições de atividades como Gerenciamento de Riscos, Modelagem de Ameaças anterior e Engenharia de Segurança.
Uma Estratégia de Teste não precisa ser formalmente documentada: pode ser descrita por meio de Histórias (em projetos Ágeis), rapidamente enumerada em listas de verificação ou especificada como casos de teste para uma determinada ferramenta. No entanto, a estratégia definitivamente deve ser compartilhada, pois precisa ser implementada por uma equipe diferente daquela que a definiu. Além disso, todas as equipes técnicas devem concordar com ela para garantir que não imponha cargas inaceitáveis a nenhuma delas.
Estratégias de Teste abordam tópicos como os seguintes:
- objetivos e descrições de riscos
- planos para atingir objetivos, redução de riscos, quais testes serão obrigatórios, quem os realizará, como e quando serão realizados
- critérios de aceitação
Para acompanhar o progresso e a eficácia da estratégia de teste, métricas devem ser definidas, atualizadas continuamente durante o projeto e comunicadas periodicamente. Um livro inteiro poderia ser escrito sobre a escolha de métricas relevantes; o máximo que podemos dizer aqui é que elas dependem de perfis de risco, projetos e organizações. Exemplos de métricas incluem:
- o número de histórias relacionadas a controles de segurança que foram implementadas com sucesso
- cobertura de código para testes unitários de controles de segurança e funcionalidades sensíveis
- o número de bugs de segurança encontrados para cada build por meio de ferramentas de análise estática
- tendências em backlogs de bugs de segurança (que podem ser classificados por urgência)
Estas são apenas sugestões; outras métricas podem ser mais relevantes para o seu projeto. As métricas são ferramentas poderosas para colocar um projeto sob controle, desde que forneçam aos gerentes de projeto uma perspectiva clara e sintética do que está acontecendo e do que precisa ser melhorado.
É importante distinguir entre testes realizados por uma equipe interna e testes realizados por um terceiro independente. Testes internos geralmente são úteis para melhorar as operações diárias, enquanto testes de terceiros são mais benéficos para toda a organização. Testes internos podem ser realizados com bastante frequência, mas testes de terceiros acontecem no máximo uma ou duas vezes por ano; além disso, os primeiros são menos dispendiosos do que os últimos. Ambos são necessários, e muitas regulamentações exigem testes de um terceiro independente porque tais testes podem ser mais confiáveis.
Testes de Segurança no Modelo Waterfall¶
O que é Waterfall e Como as Atividades de Teste são Organizadas¶
Basicamente, o SDLC (Ciclo de Vida de Desenvolvimento de Software) não exige o uso de nenhum ciclo de vida de desenvolvimento específico: é seguro afirmar que a segurança pode (e deve!) ser abordada em qualquer situação.
As metodologias Waterfall foram populares antes do século XXI. A aplicação mais famosa é chamada de "modelo em V", no qual as fases são executadas em sequência e é possível retroceder apenas uma etapa. As atividades de teste desse modelo ocorrem em sequência e são realizadas em sua maioria, principalmente no ponto do ciclo de vida em que a maior parte do desenvolvimento do aplicativo está concluída. Essa sequência de atividades significa que alterar a arquitetura e outros fatores que foram definidos no início do projeto é praticamente impossível, embora o código possa ser modificado após a identificação de defeitos.
Testes de Segurança para Agile/DevOps e DevSecOps¶
DevOps refere-se a práticas que focam em uma colaboração próxima entre todas as partes interessadas envolvidas no desenvolvimento de software (geralmente chamadas de Devs) e operações (geralmente chamadas de Ops). DevOps não se trata de fundir Devs e Ops. As equipes de desenvolvimento e operações originalmente trabalhavam em silos, quando o envio de software desenvolvido para produção podia levar um tempo significativo. Quando as equipes de desenvolvimento tornaram necessário mover mais entregas para produção ao trabalhar com Agile, as equipes de operações tiveram que acelerar para acompanhar o ritmo. DevOps é a evolução necessária da solução para esse desafio, pois permite que o software seja liberado para os usuários mais rapidamente. Isso é amplamente alcançado por meio de extensa automação de build, do processo de teste e liberação de software, e de mudanças de infraestrutura (além do aspecto de colaboração do DevOps). Essa automação é incorporada no pipeline de implantação com os conceitos de Integração Contínua e Entrega Contínua (CI/CD).
As pessoas podem assumir que o termo "DevOps" representa apenas a colaboração entre equipes de desenvolvimento e operações, no entanto, como o líder de pensamento DevOps Gene Kim coloca: "À primeira vista, parece que os problemas estão apenas entre Devs e Ops, mas o teste está lá, e você tem objetivos de segurança da informação, e a necessidade de proteger sistemas e dados. Estas são preocupações de alto nível da gerência, e elas se tornaram parte do quadro do DevOps."
Em outras palavras, a colaboração DevOps inclui equipes de qualidade, equipes de segurança e muitas outras equipes relacionadas ao projeto. Quando você ouve "DevOps" hoje, provavelmente deveria estar pensando em algo como DevOpsQATestInfoSec. De fato, os valores do DevOps pertencem a aumentar não apenas a velocidade, mas também a qualidade, segurança, confiabilidade, estabilidade e resiliência.
A segurança é tão crítica para o sucesso dos negócios quanto a qualidade geral, desempenho e usabilidade de um aplicativo. Como os ciclos de desenvolvimento são encurtados e as frequências de entrega aumentadas, garantir que qualidade e segurança sejam incorporadas desde o início torna-se essencial. DevSecOps trata exatamente de adicionar segurança aos processos do DevOps. A maioria dos defeitos é identificada durante a produção. O DevOps especifica as melhores práticas para identificar tantos defeitos quanto possível no início do ciclo de vida e para minimizar o número de defeitos no aplicativo liberado.
No entanto, o DevSecOps não é apenas um processo linear orientado a entregar o melhor software possível para operações; é também um mandato para que as operações monitorem de perto o software em produção para identificar problemas e corrigi-los formando um loop de feedback rápido e eficiente com o desenvolvimento. O DevSecOps é um processo no qual a Melhoria Contínua é fortemente enfatizada.
O aspecto humano dessa ênfase reflete-se na criação de equipes multifuncionais que trabalham juntas para alcançar resultados de negócios. Esta seção está focada nas interações necessárias e na integração da segurança no ciclo de vida de desenvolvimento (que começa com o início do projeto e termina com a entrega de valor aos usuários).
O que são Agile e DevSecOps e Como as Atividades de Teste são Organizadas¶
Visão Geral¶
A automação é uma prática fundamental do DevSecOps: como mencionado anteriormente, a frequência de entregas do desenvolvimento para a operação aumenta em comparação com a abordagem tradicional, e atividades que normalmente demandam tempo precisam acompanhar esse ritmo, por exemplo, entregar o mesmo valor agregado em menos tempo. Atividades improdutivas devem, consequentemente, ser abandonadas, e tarefas essenciais precisam ser aceleradas. Essas mudanças impactam alterações de infraestrutura, implantação e segurança:
- a infraestrutura está sendo implementada como Infrastructure as Code
- a implantação está se tornando mais scriptada, traduzida através dos conceitos de Integração Contínua e Entrega Contínua
- atividades de segurança estão sendo automatizadas tanto quanto possível e ocorrendo ao longo de todo o ciclo de vida
As seções a seguir fornecem mais detalhes sobre esses três pontos.
Infraestrutura como Código¶
Em vez de provisionar manualmente recursos de computação (servidores físicos, máquinas virtuais, etc.) e modificar arquivos de configuração, a Infraestrutura como Código baseia-se no uso de ferramentas e automação para acelerar o processo de provisionamento e torná-lo mais confiável e repetível. Os scripts correspondentes costumam ser armazenados sob controle de versão para facilitar o compartilhamento e a resolução de problemas.
As práticas de Infraestrutura como Código facilitam a colaboração entre equipes de desenvolvimento e operações, com os seguintes resultados:
- Os desenvolvedores entendem melhor a infraestrutura a partir de um ponto de vista familiar e podem preparar os recursos que o aplicativo em execução exigirá.
- As operações gerenciam um ambiente que melhor se adapta ao aplicativo e compartilham uma linguagem comum com os desenvolvedores.
A Infraestrutura como Código também facilita a construção dos ambientes necessários para projetos clássicos de criação de software, como desenvolvimento ("DEV"), integração ("INT"), testes ("PPR" para Pré-Produção. Alguns testes geralmente são realizados em ambientes anteriores, e os testes de PPR referem-se principalmente à não regressão e ao desempenho com dados similares aos utilizados em produção) e produção ("PRD"). O valor da infraestrutura como código reside na possível similaridade entre os ambientes (eles devem ser iguais).
A Infraestrutura como Código é comumente usada em projetos que possuem recursos baseados em nuvem, pois muitos fornecedores oferecem APIs que podem ser usadas para provisionar itens (como máquinas virtuais, espaços de armazenamento, etc.) e trabalhar em configurações (por exemplo, modificar tamanhos de memória ou o número de CPUs usadas por máquinas virtuais). Essas APIs fornecem alternativas para que os administradores realizem essas atividades a partir de consoles de monitoramento.
As principais ferramentas nesse domínio são Puppet, Terraform, Packer, Chef e Ansible.
Implantação¶
A sofisticação do pipeline de implantação depende da maturidade da organização do projeto ou da equipe de desenvolvimento. Em sua forma mais simples, o pipeline de implantação consiste em uma fase de commit. A fase de commit geralmente envolve a execução de verificações simples do compilador e do conjunto de testes de unidade, além da criação de um artefato implantável do aplicativo. Um candidato a release é a versão mais recente que foi verificada no tronco do sistema de controle de versão. Os candidatos a release são avaliados pelo pipeline de implantação quanto à conformidade com os padrões que devem cumprir para a implantação em produção.
A fase de commit é projetada para fornecer feedback instantâneo aos desenvolvedores e, portanto, é executada em cada commit no tronco. Restrições de tempo existem devido a essa frequência. A fase de commit geralmente deve ser concluída em até cinco minutos e não deve levar mais de dez. Aderir a essa restrição de tempo é bastante desafiador quando se trata de segurança, pois muitas ferramentas de segurança não podem ser executadas com rapidez suficiente (#paul, #mcgraw).
CI/CD significa "Integração Contínua/Entrega Contínua" em alguns contextos e "Integração Contínua/Implantação Contínua" em outros. Na verdade, a lógica é:
- As ações de build de Integração Contínua (seja acionadas por um commit ou executadas regularmente) usam todo o código-fonte para construir um candidato a release. Testes podem então ser realizados e a conformidade do release com regras de segurança, qualidade, etc., pode ser verificada. Se a conformidade for confirmada, o processo pode continuar; caso contrário, a equipe de desenvolvimento deve corrigir o(s) problema(s) e propor alterações.
- Os candidatos a release de Entrega Contínua podem prosseguir para o ambiente de pré-produção. Se o release puder então ser validado (seja manual ou automaticamente), a implantação pode continuar. Caso contrário, a equipe do projeto será notificada e a(s) ação(ões) apropriada(s) deve(m) ser tomada(s).
- Os releases de Implantação Contínua são transicionados diretamente da integração para a produção, por exemplo, tornam-se acessíveis ao usuário. No entanto, nenhum release deve ir para produção se defeitos significativos forem identificados durante as atividades anteriores.
A entrega e a implantação de aplicativos com baixa ou média sensibilidade podem ser fundidas em uma única etapa, e a validação pode ser realizada após a entrega. No entanto, manter essas duas ações separadas e usar validação robusta é fortemente recomendado para aplicativos sensíveis.
Segurança¶
Neste ponto, a grande questão é: agora que outras atividades necessárias para a entrega de código são concluídas de forma significativamente mais rápida e eficaz, como a segurança pode acompanhar? Como podemos manter um nível apropriado de segurança? Entregar valor aos usuários com mais frequência, mas com segurança reduzida, certamente não seria bom!
Mais uma vez, a resposta está na automação e em ferramentas: implementando esses dois conceitos ao longo do ciclo de vida do projeto, você pode manter e melhorar a segurança. Quanto maior o nível esperado de segurança, mais controles, pontos de verificação e ênfase serão aplicados. Seguem exemplos:
- O Static Application Security Testing (SAST) pode ocorrer durante a fase de desenvolvimento e ser integrado ao processo de Continuous Integration, com maior ou menor ênfase nos resultados da varredura. Você pode estabelecer Regras de Codificação Segura mais ou menos rigorosas e usar ferramentas de SAST para verificar a eficácia de sua implementação.
- O Dynamic Application Security Testing (DAST) pode ser executado automaticamente após a construção do aplicativo (por exemplo, após a conclusão do Continuous Integration) e antes da entrega, novamente com maior ou menor ênfase nos resultados.
- Você pode adicionar pontos de verificação de validação manual entre fases consecutivas, por exemplo, entre a entrega e a implantação.
A segurança de um aplicativo desenvolvido com DevOps deve ser considerada durante as operações. Seguem exemplos:
- Varreduras devem ocorrer regularmente (tanto em nível de infraestrutura quanto de aplicativo).
- Testes de penetração (pentesting) podem ocorrer regularmente. (A versão do aplicativo usada em produção é a que deve ser testada, e o teste deve ocorrer em um ambiente dedicado e incluir dados semelhantes aos da versão de produção. Consulte a seção sobre Teste de Penetração para mais detalhes.)
- Monitoramento ativo deve ser realizado para identificar problemas e remediá-los o mais rápido possível por meio do ciclo de feedback.

Nota: O texto contido na imagem permanece em inglês.
Referências¶
- [paul] - M. Paul. Official (ISC)2 Guide to the CSSLP CBK, Second Edition ((ISC)2 Press), 2014
- [mcgraw] - G McGraw. Software Security: Building Security In, 2006