Controles de DevSecOps

O DevSecOps aplica a segurança da inovação ao integrar processos e ferramentas de segurança no processo de desenvolvimento do DevOps.

Como o DevOps em si é uma disciplina emergente com um alto grau de variações de processo, o sucesso do DevSecOps depende da compreensão e da integração cuidadosa da segurança no processo de desenvolvimento. A adição de segurança deve começar com alterações de baixo atrito no código, nos processos de desenvolvimento e na infraestrutura que hospeda a carga de trabalho. Concentre-se primeiro nas alterações com o maior efeito positivo sobre a segurança, ao mesmo tempo que coloca uma baixa carga nos processos e nas habilidades do DevOps.

Esta documentação examina cada estágio de um processo de DevOps de CI/CD (integração contínua e entrega contínua) e quais controles de segurança recomendamos que sejam integrados primeiro.

DevSecOps controls

Planejar e desenvolver

Normalmente, o desenvolvimento moderno segue uma metodologia de desenvolvimento Agile. O Scrum é uma implementação da metodologia Agile que faz com que cada sprint comece com uma atividade de planejamento. A introdução da segurança nesta parte do processo de desenvolvimento deve se concentrar em:

  • Modelagem de ameaças para exibir o aplicativo por meio da lente de um possível invasor
  • Plug-ins de segurança do IDE e ganchos de pré-confirmação para verificação de análise estática leve em um IDE (ambiente de desenvolvimento integrado).
  • Revisões de pares e padrões de codificação seguros para identificar padrões de codificação de segurança, processos de revisão de pares e ganchos de pré-confirmação eficazes.

Não é obrigatório adicionar todas essas etapas. Mas cada etapa ajuda a revelar problemas de segurança antecipadamente, quando é muito mais barato e fácil corrigi-los.

Modelagem de ameaças

A modelagem de ameaças é, sem dúvida, a prática de segurança mais importante. Ela fornece resultados imediatos e ajuda a estabelecer uma mentalidade de segurança nos desenvolvedores, para melhorar a segurança em todos os projetos futuros.

A modelagem de ameaças é um conceito simples, embora possa ser detalhada e técnica, se necessário. A modelagem de ameaças revela e documenta uma exibição de segurança realista do aplicativo que inclui:

  • Como os invasores podem abusar do design do aplicativo
  • Como corrigir vulnerabilidades
  • A importância de corrigir os problemas

A modelagem de ameaças coloca você de fato na mentalidade de um invasor. Ela permite que você veja o aplicativo da perspectiva de um invasor. Você aprenderá a bloquear as tentativas, antes que os invasores possam fazer qualquer coisa a respeito. Se a equipe tiver personas de usuário no design, você poderá tratar o invasor como uma persona de usuário hostil.

Existem abordagens publicadas para modelagem de ameaças, que variam de métodos simples de pergunta e resposta à análise detalhada baseada em ferramentas. Você pode basear sua abordagem em metodologias como o modelo STRIDE ou a modelagem de ameaças OWASP.

Modelagem de ameaças: comece de forma simples

Como algumas abordagens à modelagem de ameaças podem ser demoradas e exigir muitas habilidades, recomendamos começar com uma abordagem mais simples usando perguntas básicas. Os métodos mais simples não são tão completos, mas iniciam o processo de raciocínio crítico e ajudam a identificar rapidamente os principais problemas de segurança.

Os métodos de perguntas simples a seguir ajudarão você a começar:

Você pode usar uma ou ambas as abordagens, dependendo do que funciona melhor para a sua equipe.

Quando a equipe estiver mais à vontade com o processo, poderá aplicar técnicas mais avançadas no ciclo de vida de desenvolvimento de segurança da Microsoft. E ela poderá integrar ferramentas de modelagem de ameaças, como a ferramenta de modelagem de ameaças da Microsoft, para obter insights mais detalhados e ajudar a automatizar o processo.

Outro recurso útil é o guia de modelagem de ameaças para desenvolvedores.

Plug-ins de segurança do IDE e ganchos de pré-confirmação

Os desenvolvedores se concentram na velocidade de entrega e os controles de segurança podem desacelerar o processo. Normalmente, a desaceleração ocorre se as verificações de segurança começarem no pipeline. Um desenvolvedor descobre sobre uma possível vulnerabilidade, depois de enviar o código para o repositório. Para acelerar o processo e fazer comentários imediatos, vale a pena adicionar etapas como plug-ins de segurança do IDE e ganchos de pré-confirmação.

Os plug-ins de segurança do IDE (ambiente de desenvolvimento integrado) identificam diferentes problemas de segurança durante o processo de desenvolvimento no ambiente IDE clássico do desenvolvedor. Os plug-ins podem fornecer comentários imediatos, se houver um possível risco de segurança no código por escrito do desenvolvedor. Os plug-ins também podem revelar riscos na biblioteca ou no pacote de terceiros. Dependendo do IDE escolhido, muitos plug-ins comerciais ou de código aberto são disponibilizados e fornecidos por empresas de segurança.

Outra etapa a ser considerada é o uso de uma estrutura de pré-confirmação, se o sistema de controle de versão permitir. Uma estrutura de pré-confirmação fornece scripts de gancho do Git, que ajudam a identificar os problemas antes que um desenvolvedor envie o código para revisão de código. Um exemplo é a pré-confirmação que você pode configurar no GitHub.

Padrões de revisão de pares e codificação segura

As solicitações de pull são padrão no processo de desenvolvimento. Parte do processo de solicitação de pull inclui as revisões em pares que geralmente revelam defeitos, bugs ou problemas não descobertos, relacionados a erros humanos. É uma boa prática ter um defensor da segurança ou um colega de equipe de segurança experiente, que possa orientar o desenvolvedor durante o processo de revisão em pares, antes de criar uma solicitação de pull.

As diretrizes de prática de codificação segura ajudam os desenvolvedores a aprender os princípios essenciais de codificação segura e como eles devem ser aplicados. Há práticas de codificação segura disponíveis, como as práticas de codificação segura OWASP, para incorporar às práticas gerais de codificação.

Confirmar o código

Normalmente, os desenvolvedores criam, gerenciam e compartilham o código em repositórios como o GitHub ou o Azure Repos. Essa abordagem fornece uma biblioteca de código central com controle de versão para desenvolvedores, para uma fácil colaboração. No entanto, permitir muitos colaboradores em uma única base de código também pode correr o risco de introduzir alterações. Esse risco pode levar a vulnerabilidades ou à inclusão não intencional de credenciais ou tokens nas confirmações.

Para resolver esse risco, as equipes de desenvolvimento devem avaliar e implementar uma funcionalidade de verificação de repositório. As ferramentas de verificação de repositório executam análises de código estático no código-fonte nos repositórios. As ferramentas procuram vulnerabilidades ou alterações de credenciais e sinalizam os itens encontrados para correção. Essa funcionalidade protege contra erros humanos, além de ser uma garantia útil para equipes distribuídas em que muitas pessoas estão colaborando no mesmo repositório.

Gerenciamento de dependência

Até 90% do código nos aplicativos atuais contêm elementos de bibliotecas e pacotes externos e se baseiam neles. Com a adoção de dependências no código-fonte, é essencial resolver possíveis riscos. Muitas bibliotecas de terceiros têm sérios problemas de segurança. Além disso, os desenvolvedores não seguem consistentemente o melhor ciclo de vida nem mantêm as dependências atualizadas.

Verifique se a equipe de desenvolvimento sabe quais componentes devem ser incluídos nos aplicativos. Convém baixar as versões seguras e atualizadas de fontes conhecidas. E convém ter um processo para manter as versões atualizadas. A equipe pode usar ferramentas como o projeto de Verificação de Dependência OWASP, o WhiteSource, entre outras.

Concentrar-se nas vulnerabilidades de dependência ou no ciclo de vida não é suficiente. Também é importante abordar a segurança dos feeds de pacotes. Existem vetores de ataque conhecidos que visam os sistemas de gerenciamento de pacotes: typosquatting, comprometimento de pacotes existentes, ataques de substituição, entre outros. Portanto, a administração responsável pelo gerenciamento de pacotes deve resolver esses riscos. Para obter mais informações, confira Três maneiras de atenuar o risco ao usar feeds de pacotes privados.

Teste de segurança de aplicativo estático

Depois que a equipe aborda o gerenciamento de bibliotecas e pacotes de terceiros, é essencial mudar o foco e melhorar a segurança do código. Existem maneiras diferentes de melhorar a segurança de código. Você pode usar os plug-ins de segurança do IDE. Ou você pode conectar as verificações de confirmação e pré-confirmação de análise estática incremental, conforme discutido antes. Também é possível fazer uma verificação completa do código-fonte, para capturar erros que passaram despercebidos nas etapas anteriores. É necessário, mas pode levar horas ou até mesmo dias para verificar em um grande bloco de código. Portanto, essa abordagem pode desacelerar o desenvolvimento e introduzir uma sobrecarga.

Mas uma equipe deve começar em algum lugar, ao implementar práticas de verificação de código estático. Uma maneira é introduzir a análise de código estático dentro da integração contínua. Esse método verifica a segurança assim que as alterações de código acontecem. Um exemplo é o SonarCloud. Ele envolve várias ferramentas de SAST (teste de segurança de aplicativo estático) para diferentes linguagens. O SonarCloud avalia e acompanha a dívida técnica com foco na facilidade de manutenção. Ele examina a qualidade e o estilo do código e tem verificadores específicos de segurança. Mas existem muitas outras ferramentas comerciais e de código aberto disponíveis no mercado.

Para garantir que o ciclo de comentários seja eficaz, é fundamental ajustar a ferramenta. Convém minimizar os falsos positivos e fornecer comentários claros e acionáveis sobre os problemas a serem corrigidos. Além disso, é bom implementar um fluxo de trabalho, o que impede a confirmação de código no branch padrão, se houver conclusões. Convém contemplar as conclusões de qualidade e segurança. Portanto, a segurança se torna parte da experiência de teste de unidade.

Pipelines seguros

O DevOps leva a automação a outro nível, pois tudo no ciclo de vida de desenvolvimento passa por um pipeline. A CI/CD (integração contínua e entrega contínua) é uma parte importante dos ciclos de desenvolvimento modernos. Na CI/CD, a equipe mescla o código do desenvolvedor em uma base de código central regularmente e executa automaticamente as compilações e os processos de teste padrão.

Os pipelines de infraestrutura são uma parte central do desenvolvimento. Mas o uso de pipelines para executar scripts ou implantar código nos ambientes de produção pode apresentar desafios de segurança exclusivos. Convém garantir que os pipelines de CI/CD não se tornem locais para executar códigos mal-intencionados, permitir que as credenciais sejam roubadas ou fornecer aos invasores qualquer área de superfície para acesso. Além disso, convém garantir que apenas o código que a equipe pretende liberar seja implantado.

As equipes do DevOps devem implementar os controles de segurança adequados para o pipeline. Dependendo da plataforma escolhida, existem diferentes diretrizes sobre como lidar com os riscos. Para obter mais informações, confira Como proteger o Azure Pipelines.

Build e teste

Muitas organizações usam pipelines de build e de lançamento para automatizar e padronizar os processos de criação e implantação de código. Os pipelines de lançamento permitem que as equipes de desenvolvimento façam alterações iterativas nas seções de código de forma rápida e em escala. As equipes não precisarão gastar muito tempo reimplantando ou atualizando os ambientes existentes.

O uso de pipelines de lançamento também permite que as equipes promovam o código em ambientes de desenvolvimento, por meio de ambientes de teste e, por fim, na produção. Como parte da automação, as equipes de desenvolvimento devem incluir ferramentas de segurança que executem testes automatizados com script, ao implantar código nos ambientes de teste. Os testes devem incluir testes de unidade nos recursos de aplicativo, para verificar se há vulnerabilidades ou pontos de extremidade públicos. O teste garante o acesso intencional.

Teste de segurança de aplicativo dinâmico

Em um modelo clássico de desenvolvimento em cascata, a segurança era normalmente apresentada na última etapa, pouco antes de ir para a produção. Uma das abordagens de segurança mais populares é o teste de penetração. O teste de penetração permite que uma equipe analise o aplicativo de uma perspectiva de segurança de caixa preta, como se fosse em uma mentalidade de invasor.

Um teste de penetração consiste em vários pontos de ação, um deles é o DAST (teste de segurança de aplicativo dinâmico). O DAST é um teste de segurança de aplicativo Web, que encontra problemas de segurança no aplicativo em execução, observando como o aplicativo responde a solicitações especialmente criadas. As ferramentas de DAST também são conhecidas como scanners de vulnerabilidade de aplicativo Web. Um exemplo é uma ferramenta de código aberto, OWASP ZAP (Zed Attack Proxy). Ele encontra vulnerabilidades no aplicativo Web em execução. Existem várias maneiras diferentes em que o OWASP ZAP verifica: uma verificação de linha de base passiva ou uma verificação completa, dependendo da configuração.

A desvantagem do teste de penetração é que ele é demorado. Um teste de penetração completo pode levar até várias semanas e, considerando a velocidade do desenvolvimento do DevOps, esse período pode ser insustentável. Mas, ainda vale a pena adicionar uma versão mais leve do teste de penetração, durante o processo de desenvolvimento, para descobrir problemas que passaram despercebidos no SAST e nas outras etapas. As ferramentas de DAST, como o OWASP ZAP, podem ajudar.

Os desenvolvedores integram o OWASP ZAP no pipeline como tarefa. Durante a execução, o verificador do OWASP ZAP gira no contêiner, faz a verificação e depois publica os resultados. Essa abordagem pode não ser perfeita, pois não é um teste de penetração completo, mas ainda é importante. É mais uma medida de qualidade no ciclo de desenvolvimento, para melhorar a postura de segurança.

Validação da configuração de nuvem e verificação de infraestrutura

Juntamente com a verificação e a proteção do código para aplicativos, verifique se os ambientes em que você implantou os aplicativos também estão seguros. Ambientes seguros são fundamentais para organizações que desejam avançar, inovar e usar novas tecnologias. Ambientes seguros também ajudam as equipes a criar novos ambientes rapidamente para experimentação.

Os recursos do Azure permitem que as organizações criem padrões de segurança nos ambientes, como o Azure Policy. As equipes podem usar o Azure Policy para criar conjuntos de políticas. Os conjuntos de políticas impedem a criação de determinados tipos de carga de trabalho ou itens de configuração, como endereços IP públicos. Esses verificadores de integridade permitem que as equipes façam experimentos em um ambiente seguro e controlado, equilibrando inovação e governança.

Uma das maneiras pelas quais o DevOps pode aproximar desenvolvedores e operações é dar suporte à conversão da infraestrutura existente em uma abordagem de infraestrutura como código.

A IaC (infraestrutura como código) é o gerenciamento de infraestrutura (redes, máquinas virtuais, balanceadores de carga e topologia de conexão) em um modelo descritivo. A IaC usa o mesmo modelo de controle de versão que a equipe do DevOps usa para código-fonte. Como o princípio de que o mesmo código-fonte gera o mesmo binário, um modelo IaC gera o mesmo ambiente sempre que ele é aplicado. IaC é uma prática de DevOps importante usada com entrega contínua.

O DevSecOps executa o teste de shift-left na segurança e mostra que a segurança não se trata apenas da segurança do aplicativo, mas também da segurança da infraestrutura. Uma das maneiras pelas quais o DevSecOps dá suporte à segurança de infraestrutura é incluir a verificação de segurança antes que a infraestrutura seja implantada na nuvem. À medida que a infraestrutura se tornasse código, você aplicaria as mesmas ações de segurança à infraestrutura que a segurança do aplicativo. Existem ferramentas de segurança disponíveis para executar a verificação de segurança de infraestrutura com base na estratégia de IaC escolhida.

Com a adoção da nuvem, a conteinerização é uma abordagem popular que as equipes seguem nas decisões de arquitetura de aplicativo. Alguns dos repositórios de contêineres verificam as imagens para capturar os pacotes com as vulnerabilidades conhecidas. Ainda existe o risco de que um contêiner possa ter o software desatualizado. Por causa desse risco, é essencial verificar o contêiner quanto a riscos de segurança. Existem muitas ferramentas de segurança comerciais e de código aberto, que visam essa área e permitem a integração completa no processo de CD. As ferramentas de segurança ajudam as equipes a adotar o DevSecOps para infraestrutura como código e, mais especificamente, aprender a usar contêineres.

Ir para produção e operar

Quando a solução vai para a produção, é essencial continuar supervisionando e gerenciando o estado de segurança. Nessa fase do processo, é hora de se concentrar na infraestrutura de nuvem e no aplicativo em geral.

Configuração e verificação de infraestrutura

Para obter visibilidade das assinaturas de nuvem e da configuração de recursos em várias assinaturas, use a solução de segurança de locatário do Azure da equipe do AzSK.

O Azure inclui funcionalidades de monitoramento e segurança. Essas funcionalidades detectam e alertam sobre configurações ou eventos anômalos que exigem investigação e uma possível correção. Tecnologias como o Microsoft Defender para Nuvem e o Microsoft Sentinel são ferramentas próprias integradas nativamente aos ambientes do Azure. Essas tecnologias complementam as ferramentas de segurança de código e ambiente. E as tecnologias fornecem monitoramento de segurança completo para que as organizações possam experimentar e inovar de forma rápida e segura.

Teste de penetração

O teste de penetração é uma prática recomendada para verificar se há vulnerabilidades na infraestrutura ou na configuração do aplicativo, que podem criar pontos fracos que os invasores podem explorar.

Muitos produtos e parceiros oferecem serviços de teste de penetração. A Microsoft fornece as diretrizes para o teste de penetração no Azure.

Os testes normalmente abrangem os seguintes tipos de teste:

  • Testes nos pontos de extremidade para descobrir vulnerabilidades
  • Teste de fuzzing (localizar erros de programa fornecendo dados de entrada malformados) dos pontos de extremidade
  • Exame de portas de seus pontos de extremidade

Inteligência acionável

As ferramentas e técnicas nestas diretrizes oferecem um modelo de segurança holístico para organizações que desejam avançar e experimentar novas tecnologias que visam gerar inovação. Um elemento-chave do DevSecOps consiste em processos controlados por dados e por eventos. Esses processos ajudam as equipes a identificar, avaliar e responder a possíveis riscos. Muitas organizações optam por integrar alertas e dados de uso à plataforma de ITSM (gerenciamento de serviços de TI). A equipe pode levar o mesmo fluxo de trabalho estruturado para os eventos de segurança usados para outros incidentes e solicitações.

Loops de comentários

Screenshot showing the Continuous security model.

Todas essas técnicas e ferramentas capacitam as equipes para localizar e sinalizar riscos e vulnerabilidades que exigem investigação e uma possível resolução. As equipes de operações que recebem um alerta ou descobrem um possível problema, quando investigam um tíquete de suporte, precisam de uma rota de volta para a equipe de desenvolvimento para sinalizar os itens para revisão. Um loop de comentários suave e colaborativo é essencial para resolver problemas rapidamente e minimizar o risco de uma vulnerabilidade o máximo possível.

Um padrão comum de comentários é integrá-lo a um sistema de gerenciamento de trabalho do desenvolvedor, como o Azure DevOps ou o GitHub. Uma organização pode vincular alertas ou incidentes a itens de trabalho para que os desenvolvedores planejem e acionem. Esse processo fornece uma maneira eficaz para os desenvolvedores resolverem problemas no fluxo de trabalho padrão, incluindo desenvolvimento, teste e lançamento.