Compartilhar via


Recomendações para proteger um ciclo de vida de desenvolvimento

Aplica-se a esta recomendação de lista de verificação do Azure Well-Architected Framework Security:

SE:02 Mantenha um ciclo de vida de desenvolvimento seguro usando uma cadeia de suprimentos de software reforçada, principalmente automatizada e auditável. Incorpore um design seguro usando a modelagem de ameaças para proteger contra implementações que anulam a segurança.

Guia relacionado: Análise de ameaças

Este guia descreve as recomendações para proteger seu código, ambiente de desenvolvimento e cadeia de suprimentos de software aplicando as melhores práticas de segurança em todo o ciclo de desenvolvimento. Para entender essas diretrizes, você deve ter conhecimento de DevSecOps.

Um diagrama do ciclo de segurança.

O DevSecOps integra a segurança aos processos de DevOps:

  • Automatizando testes e validação de segurança.

  • Implementação de ferramentas como pipelines de segurança para verificar código e infraestrutura como código (IaC) em busca de vulnerabilidades.

No centro de uma carga de trabalho está o código do aplicativo que implementa a lógica de negócios. O código e o processo de desenvolvimento do código devem estar livres de defeitos de segurança para garantir confidencialidade, integridade e disponibilidade.

Não basta proteger apenas o plano de infraestrutura usando controles de identidade e rede e outras medidas. Evite a implementação incorreta de código ou um bloco de código comprometido para fortalecer sua postura geral de segurança. O plano de uso, ou seja, o código do aplicativo, também deve ser protegido. O processo de integração da segurança em seu ciclo de vida de desenvolvimento é essencialmente um processo de proteção. Assim como a proteção de recursos, o desenvolvimento de código também é independente de contexto. O foco está em aumentar a segurança e não nos requisitos funcionais do aplicativo. Para obter informações relacionadas à proteção, consulte Recomendações para proteção de recursos.

Definições

Termo Definição
SDL (Security Development Lifecycle) Um conjunto de práticas fornecidas pela Microsoft que dá suporte à garantia de segurança e aos requisitos de conformidade.
Ciclo de vida de desenvolvimento de software (SDLC) Um processo sistemático de vários estágios para o desenvolvimento de sistemas de software.

Principais estratégias de design

As medidas de segurança devem ser integradas em vários pontos do Ciclo de Vida de Desenvolvimento de Software (SDLC) existente para garantir:

  • As escolhas de design não levam a lacunas de segurança.

  • O código e a configuração do aplicativo não criam vulnerabilidades devido à implementação explorável e práticas de codificação inadequadas.

  • O software adquirido por meio da cadeia de suprimentos não introduz ameaças à segurança.

  • O código do aplicativo, os processos de build e implantação não são adulterados.

  • As vulnerabilidades reveladas por meio de incidentes são mitigadas.

  • Os ativos não utilizados são devidamente desativados.

  • Os requisitos de conformidade não são comprometidos ou reduzidos.

  • O log de auditoria é implementado em ambientes de desenvolvedor.

As seções a seguir fornecem estratégias de segurança para as fases comumente praticadas do SDLC.

Colete e documente os requisitos de segurança

O objetivo da fase de requisitos é reunir e analisar os requisitos funcionais e não funcionais de um aplicativo ou de um novo recurso de um aplicativo. Essa fase é importante porque facilita a criação de proteções adaptadas aos objetivos do aplicativo. Proteger os dados e a integridade do seu aplicativo deve ser um requisito essencial em todas as fases do ciclo de vida do desenvolvimento.

Por exemplo, considere um aplicativo que precisa dar suporte a fluxos de usuário críticos que permitem que o usuário carregue e manipule dados. As opções de design de segurança devem abranger garantias para a interação do usuário com o aplicativo, como autenticar e autorizar a identidade do usuário, permitir apenas ações permitidas nos dados e impedir a injeção de SQL. Da mesma forma, cubra requisitos não funcionais, como disponibilidade, escalabilidade e capacidade de manutenção. As opções de segurança devem incluir limites de segmentação, entrada e saída de firewall e outras preocupações de segurança transversais.

Todas essas decisões devem levar a uma boa definição da postura de segurança do aplicativo. Documente os requisitos de segurança em uma especificação acordada e reflita-os na lista de pendências. Deve declarar explicitamente os investimentos em segurança e as compensações e riscos que a empresa está disposta a assumir se os investimentos não forem aprovados pelas partes interessadas da empresa. Por exemplo, você pode documentar a necessidade de usar um WAF (firewall de aplicativo Web) na frente do seu aplicativo, como o Azure Front Door ou o Gateway de Aplicativo do Azure. Se as partes interessadas de negócios não estiverem preparadas para aceitar o custo adicional de executar um WAF, elas precisarão aceitar o risco de que os ataques na camada de aplicativo possam ser direcionados ao aplicativo.

A coleta de requisitos de segurança é uma parte crítica desta fase. Sem esse esforço, as fases de design e implementação serão baseadas em escolhas não declaradas, o que pode levar a lacunas de segurança. Talvez seja necessário alterar a implementação posteriormente para acomodar a segurança, o que pode ser caro.

Traduza os requisitos de segurança em requisitos técnicos

Durante a fase de projeto, os requisitos de segurança são convertidos em requisitos técnicos. Em sua especificação técnica, documente todas as decisões de design para evitar ambiguidade durante a implementação. Aqui estão algumas tarefas típicas:

Definir a dimensão de segurança da arquitetura do sistema

Sobreponha a arquitetura com controles de segurança. Por exemplo, controles práticos sobre os limites de isolamento de acordo com sua estratégia de segmentação, os tipos de identidades necessárias para os componentes do aplicativo e o tipo de métodos de criptografia a serem usados. Para obter algumas arquiteturas de exemplo, consulte as ilustrações nas seções Exemplo dos artigos Gerenciamento de identidade e acesso e Rede.

Avalie as funcionalidades fornecidas pela plataforma

É importante entender a divisão de responsabilidade entre você e o provedor de nuvem. Evite a sobreposição com os controles de segurança nativos do Azure, por exemplo. Você obterá uma melhor cobertura de segurança e poderá realocar recursos de desenvolvimento para as necessidades do aplicativo.

Por exemplo, se o design chamar um firewall de aplicativo Web na entrada, você poderá descarregar essa responsabilidade para um balanceador de carga, como o Gateway de Aplicativo ou o Azure Front Door. Evite replicar recursos como código personalizado em seu aplicativo.

Escolha apenas estruturas, bibliotecas e software de cadeia de suprimentos confiáveis. Seu design também deve especificar o controle de versão seguro. As dependências do aplicativo devem ser originadas de partes confiáveis. Os fornecedores terceirizados devem ser capazes de atender aos seus requisitos de segurança e compartilhar seu plano de divulgação responsável. Qualquer incidente de segurança deve ser prontamente relatado para que você possa tomar as medidas necessárias. Além disso, determinadas bibliotecas podem ser proibidas por sua organização. Por exemplo, o software pode estar protegido contra vulnerabilidades, mas ainda não permitido devido a restrições de licenciamento.

Para garantir que essas diretrizes sejam seguidas por todos os colaboradores do software, mantenha uma lista de estruturas, bibliotecas e fornecedores aprovados e/ou não aprovados. Quando possível, coloque proteções nos pipelines de desenvolvimento para dar suporte à lista. Tanto quanto possível, automatize o uso de ferramentas para verificar dependências em busca de vulnerabilidades.

Determine os padrões de design de segurança que o código do aplicativo deve implementar.

Os padrões podem dar suporte a preocupações de segurança, como segmentação e isolamento, autorização forte, segurança uniforme de aplicativos e protocolos modernos. Alguns padrões operacionais, como o padrão Quarentena, podem ajudar a verificar e bloquear o uso de software que pode introduzir vulnerabilidades de segurança.

Para obter mais informações, consulte Padrões de design de nuvem que oferecem suporte à segurança.

Armazene segredos de aplicativos com segurança

Implemente com segurança o uso de segredos de aplicativo e chaves pré-compartilhadas que seu aplicativo usa. Credenciais e segredos do aplicativo nunca devem ser armazenados na árvore de código-fonte. Use recursos externos como o Azure Key Vault para garantir que, se o código-fonte ficar disponível para um invasor em potencial, nenhum acesso adicional possa ser obtido. Em geral, encontre maneiras de evitar segredos. Usar identidades gerenciadas, quando possível, é uma maneira de atingir esse objetivo. Para obter mais informações, consulte Recomendações para gerenciar segredos de aplicativo.

Definir planos de teste

Defina casos de teste claros para requisitos de segurança. Avalie se você pode automatizar esses testes em seus pipelines. Se sua equipe tiver processos para testes manuais, inclua requisitos de segurança para esses testes.

Observação

Execute a modelagem de ameaças durante esta fase. A modelagem de ameaças pode confirmar que as opções de design estão alinhadas com os requisitos de segurança e expor lacunas que você deve mitigar. Se sua carga de trabalho lida com dados altamente confidenciais, invista em especialistas em segurança que podem ajudá-lo a realizar a modelagem de ameaças.

O exercício inicial de modelagem de ameaças deve ocorrer durante a fase de design, quando a arquitetura do software e o design de alto nível estão sendo definidos. Fazer isso durante essa fase ajuda a identificar possíveis problemas de segurança antes que eles sejam incorporados à estrutura do sistema. No entanto, este exercício não é uma atividade única. É um processo contínuo que deve continuar ao longo da evolução do software.

Para obter mais informações, consulte Recomendações para análise de ameaças.

Práticas seguras de desenvolvimento e teste

Durante a fase de desenvolvimento e teste, o objetivo é evitar defeitos de segurança e adulteração em pipelines de código, build e implantação.

Seja bem treinado em práticas de código seguro

A equipe de desenvolvimento deve ter treinamento formal e especializado em práticas de codificação seguras. Por exemplo, os desenvolvedores da Web e de API podem precisar de treinamento específico para se proteger contra ataques de script entre sites, e os desenvolvedores de back-end podem se beneficiar de um treinamento aprofundado para evitar ataques no nível do banco de dados, como ataques de injeção de SQL.

Os desenvolvedores devem ser obrigados a concluir esse treinamento antes de obter acesso ao código-fonte de produção.

Você também deve realizar revisões internas de código por pares para promover o aprendizado contínuo.

Use ferramentas de teste de segurança

Execute a modelagem de ameaças para avaliar a segurança da arquitetura do aplicativo.

Use o teste de segurança de aplicativo estático (SAST) para analisar o código em busca de vulnerabilidades. Integre essa metodologia ao ambiente do desenvolvedor para detectar vulnerabilidades em tempo real.

Use o teste dinâmico de segurança de aplicativos (DAST) durante o tempo de execução. Essa cadeia de ferramentas pode verificar erros em domínios de segurança e simular um conjunto de ataques para testar a resiliência de segurança do aplicativo. Quando possível, integre essa ferramenta aos pipelines de build.

Siga os padrões do setor para práticas de codificação seguras. Para obter mais informações, consulte a seção Recursos da comunidade deste artigo.

Use linters e analisadores de código para impedir que as credenciais sejam enviadas para o repositório de código-fonte. Por exemplo, os analisadores do .NET Compiler Platform (Roslyn) inspecionam o código do aplicativo.

Durante o processo de build, use complementos de pipeline para capturar credenciais no código-fonte. Verificar todas as dependências, como bibliotecas de terceiros e componentes de estrutura, como parte do processo de integração contínua. Investigue os componentes vulneráveis sinalizados pela ferramenta. Combine essa tarefa com outras de verificação de código que inspecionam rotatividade de código, resultados de teste e cobertura.

Use uma combinação de testes. Para obter informações sobre testes de segurança em geral, consulte Recomendações para testes de segurança.

Escreva código suficiente

Ao reduzir o volume de código, você também reduz as chances de defeitos de segurança. Reutilize código e bibliotecas que já estão em uso e passaram por validações de segurança em vez de duplicar o código.

Aproveitar os recursos do Azure é outra maneira de evitar código desnecessário. Uma maneira é usar serviços gerenciados. Para obter mais informações, consulte Usar as opções de PaaS (plataforma como serviço).

Escreva código com uma abordagem de negação de tudo por padrão. Crie listas de permissões somente para entidades que precisam de acesso. Por exemplo, se você tiver um código que precise determinar se uma operação privilegiada deve ser permitida, você deverá escrevê-lo para que o resultado da negação seja o caso padrão e o resultado da permissão ocorra somente quando especificamente permitido pelo código.

Proteja os ambientes de desenvolvedor

As estações de trabalho do desenvolvedor precisam ser protegidas com fortes controles de rede e identidade para evitar a exposição. Certifique-se de que as atualizações de segurança sejam aplicadas diligentemente.

Os agentes de compilação são altamente privilegiados e têm acesso ao servidor de compilação e ao código. Eles devem ser protegidos com o mesmo rigor que os componentes da carga de trabalho. Isso significa que o acesso aos agentes de compilação deve ser autenticado e autorizado, eles devem ser segmentados em rede com controles de firewall, devem estar sujeitos à verificação de vulnerabilidades e assim por diante. Os agentes de build hospedados pela Microsoft devem ser preferidos em relação aos agentes de build auto-hospedados. Os agentes hospedados pela Microsoft fornecem benefícios como máquinas virtuais limpas para cada execução de um pipeline.

Os agentes de build personalizados adicionam complexidade de gerenciamento e podem se tornar um vetor de ataque. As credenciais da máquina de compilação devem ser armazenadas com segurança e você precisa remover regularmente todos os artefatos de compilação temporários do sistema de arquivos. Você pode obter o isolamento de rede permitindo apenas o tráfego de saída do agente de build, pois ele está usando o modelo de pull de comunicação com o Azure DevOps.

O repositório de código-fonte também deve ser protegido . Conceda acesso a repositórios de código com base na necessidade de conhecimento e reduza a exposição de vulnerabilidades o máximo possível para evitar ataques. Tenha um processo completo para revisar o código em busca de vulnerabilidades de segurança. Use grupos de segurança para essa finalidade e implemente um processo de aprovação baseado em justificativas comerciais.

Proteger o código em pipelines de implantação

Não basta apenas proteger o código. Se ele for executado em pipelines exploráveis, todos os esforços de segurança serão inúteis e incompletos. Os ambientes de build e lançamento também devem ser protegidos porque você deseja impedir que agentes mal-intencionados executem código mal-intencionado em seu pipeline.

Mantenha um inventário atualizado de todos os componentes integrados ao seu aplicativo

Cada novo componente integrado a um aplicativo aumenta a superfície de ataque. Para garantir a responsabilidade e o alerta adequados quando novos componentes são adicionados ou atualizados, você deve ter um inventário desses componentes. Armazene-o fora do ambiente de compilação. Regularmente, verifique se o manifesto corresponde ao que está no processo de compilação. Isso ajuda a garantir que nenhum novo componente que contenha backdoors ou outro malware seja adicionado inesperadamente.

Tarefas de pipeline

  • Efetue pull de tarefas em seu pipeline de fontes confiáveis, como o Azure Marketplace. Execute tarefas gravadas pelo fornecedor do pipeline. Recomendamos tarefas do GitHub ou GitHub Actions. Se você usar fluxos de trabalho do GitHub, prefira tarefas criadas pela Microsoft. Além disso, valide as tarefas porque elas são executadas no contexto de segurança do pipeline.

  • Segredos do pipeline. Os ativos de implantação executados dentro de um pipeline têm acesso a todos os segredos desse pipeline. Tenha uma segmentação adequada para diferentes estágios do pipeline para evitar exposição desnecessária. Use repositórios secretos integrados ao pipeline. Lembre-se de que você pode evitar o uso de segredos em algumas situações. Explore o uso de identidades de carga de trabalho (para autenticação de pipeline) e identidades gerenciadas (para autenticação de serviço a serviço).

Mantenha diferentes ambientes separados

Os dados usados em diferentes ambientes devem ser mantidos separados. Os dados de produção não devem ser usados em ambientes inferiores porque esses ambientes podem não ter os controles de segurança rígidos que a produção tem. Evite conectar-se de um aplicativo de não produção a um banco de dados de produção e evite conectar componentes de não produção a redes de produção.

Exposição progressiva

Use a exposição progressiva para liberar recursos para um subconjunto de usuários com base nos critérios escolhidos. Se houver problemas, o impacto será minimizado para esses usuários. Essa abordagem é uma estratégia comum de mitigação de risco porque reduz a área de superfície. À medida que o recurso amadurece e você tem mais confiança nas garantias de segurança, pode liberá-lo gradualmente para um conjunto mais amplo de usuários.

Proteger o código em produção

A fase de produção apresenta a última oportunidade responsável para corrigir as lacunas de segurança. Mantenha um registro da imagem dourada que é lançada em produção.

Manter artefatos versionados

Mantenha um catálogo de todos os ativos implantados e suas versões. Essas informações são úteis durante a triagem de incidentes, quando você está mitigando problemas e quando está colocando o sistema de volta ao estado de funcionamento. Os ativos com versão também podem ser comparados com os avisos de CVE (Vulnerabilidades e Exposições Comuns) publicados. Você deve usar a automação para executar essas comparações.

Correções de emergência

Seu projeto de pipeline automatizado deve ter a flexibilidade de suportar implantações regulares e de emergência. Essa flexibilidade é importante para dar suporte a correções de segurança rápidas e responsáveis.

Uma versão normalmente está associada a vários portões de aprovação. Considere a criação de um processo de emergência para acelerar as correções de segurança. O processo pode envolver comunicação entre as equipes. O pipeline deve permitir implantações rápidas de roll-forward e rollback que abordam correções de segurança, bugs críticos e atualizações de código que ocorrem fora do ciclo de vida regular da implantação.

Observação

Sempre priorize as correções de segurança em vez da conveniência. Uma correção de segurança não deve introduzir uma regressão ou bug. Se você quiser acelerar a correção por meio de um pipeline de emergência, considere cuidadosamente quais testes automatizados podem ser ignorados. Estime o valor de cada teste em relação ao tempo de execução. Por exemplo, os testes de unidade geralmente são concluídos rapidamente. A execução de testes de integração ou de ponta a ponta podem ser muito demorada.

Mantenha a segurança do código durante todo o seu ciclo de vida

O objetivo desta fase é garantir que a postura de segurança não diminua com o tempo. O SDLC é um processo ágil contínuo. Os conceitos abordados nas fases anteriores se aplicam a essa fase porque os requisitos mudam com o tempo.

Gerenciamento de patch. Mantenha software, bibliotecas e componentes de infraestrutura atualizados com patches e atualizações de segurança.

Melhoria contínua. Avalie e melhore continuamente a segurança do processo de desenvolvimento de software, levando em consideração revisões de código, feedback, lições aprendidas e ameaças em evolução.

Descomissione ativos legados que estão obsoletos ou não estão mais em uso. Isso reduz a área de superfície do aplicativo.

A manutenção também inclui correções de incidentes. Se forem encontrados problemas na produção, eles precisam ser prontamente integrados de volta ao processo para que não se repitam.

Melhore continuamente suas práticas de codificação segura para acompanhar o cenário de ameaças.

Facilitação do Azure

O SDL (Ciclo de Vida de Desenvolvimento de Segurança) da Microsoft recomenda práticas seguras que você pode aplicar ao seu ciclo de vida de desenvolvimento. Para obter mais informações, consulte Ciclo de vida de desenvolvimento de segurança da Microsoft.

O Defender para DevOps e as ferramentas SAST estão incluídos como parte do GitHub Advanced Security ou do Azure DevOps. Essas ferramentas podem ajudá-lo a rastrear uma pontuação de segurança para sua organização.

Siga as recomendações de segurança do Azure descritas nestes recursos:

Para encontrar credenciais no código-fonte, considere usar ferramentas como GitHub Advanced Security e ferramentas de análise de código-fonte OWASP.

Valide a segurança de qualquer código-fonte aberto em seu aplicativo. Estas ferramentas e recursos gratuitos podem ajudá-lo com sua avaliação:

Lista de verificação de segurança

Consulte o conjunto completo de recomendações.