Entendendo o ciclo de vida do desenvolvimento de software seguro (SSDLC)
Durante o desenvolvimento de software, alguns termos têm chamado cada vez mais a atenção: CI, CD, SDLC e SSDLC.
Dessa maneira, resolvi explicar alguns desses termos para ajudar as pessoas que estão iniciando por esse mundo da computação. Como também, explicar o ciclo de vida de um software e também, o papel de um Application Security Engineer em todo esse processo.
Quando pensamos, no desenvolvimento de um software, existe uma história por onde ele se inicia até se tornar um produto que possa ser escalável. Portanto, existe um Ciclo de vida de desenvolvimento de software — Software Development Life Cycle (SDLC).
Conforme a imagem, temos as seguintes etapas para serem descritas:
1- Requerimento: Nessa fase, iremos buscar as informações com o Stakeholder (dono) do projeto para entendermos qual é a "dor" dele. Devemos entender o que ele espera daquele produto/software, quais funcionalidades devem existir para que esse produto possa gerar valor.
2- Planejamento: Nessa fase, iremos planejar quanto tempo imaginamos que seja necessário para desenvolver aquele produto, quantas pessoas serão necessárias para realizar esse projeto. Além de listarmos quais recursos serão necessários para a realização desse software, como framework escolhido, linguagem de programação e tipo de servidor. Muita das vezes usamos alguns softwares como o Jira ou Trello para ajudar nessa planejamento e tarefas que poderão ser realizadas nesse processo.
3- Arquitetura: Nessa fase, iremos discutir a arquitetura necessária para criarmos um produto escalável, qual a infraestrutura que pensamos em realizar ou se usaremos microserviço ou um sistema monolítico, por exemplo. Além disso, podemos desenhar as tecnologias necessárias para esse projeto ocorrer, pensando no fluxo de dados daquela aplicação. Como por exemplo, qual tipo de banco de dados, se ele será NoSQL ou SQL, se poderá ocorrer algum tipo de incompatibilidade, se terá o uso de algum produto externo, qual tipo de comunicação, se utilização REST ou não, por exemplo. Nessa fase, utilizam-se ferramentas de desenho de fluxo. Uma ferramenta bem simples e leve é o Diagram.net , por exemplo.
4- Desenvolvimento de Software: Nessa fase, é onde o desenvolvedor irá desenvolver a aplicação, seguindo alguma metodologia. Por exemplo, metodologia ágil para tornar mais eficiente as entregas do software. Além disso, existem alguns padrões de desenvolvimento de software e um dos mais comentados, é sem dúvida o Clean Code. Ele é bastante necessário, pois permite que o desenvolvedor tenha em mente que deve sempre criar um código simples, com poucas funções e com um código que seja bem explicativo, pois assim, também evita que seja colocado comentários durante o código.
5- Teste: Nessa fase, é onde podemos encontrar testes de qualidade da aplicação. Como por exemplo, para entendermos o comportamento da aplicação, interagindo com a tela desse software, podemos utilizar o BDD (Behaviour Driven Development).
6- Deployment: Nessa fase, é aonde expomos nossa aplicação após ter passado por todos os testes de qualidade e validando que a aplicação está apta para ser exposta. Ela pode ser exposta internamente, na Intranet para os demais funcionários da empresa ou de forma pública, na Internet.
Agora que entendemos o processo de como um software se inicia, temos alguns pontos para serem adicionados! Nesse caso, iremos implementar a segurança no processo de desenvolvimento. Portanto, teremos o início do SSDLC (Secure Software Development Life Cycle).
Dessa forma, colocaremos a segurança desde o início do nosso processo e essa abordagem é conhecida como Secure Shift Left. Além disso, vale lembrar quais são os três princípios da segurança e por meio desses princípios que precisamos pensar em como a aplicação irá funcionar: CID — Confiabilidade, Integridade e Disponibilidade. Se algum desses princípios falhar, certamente, teremos uma falha de segurança na aplicação.
Assim, quando estivermos na fase de requisito, passaremos a nos preocupar com esses princípios discutidos anteriormente. Buscaremos entender o que será necessário para criarmos um software seguro, onde o dado não pode ser alterado. Como também, precisa se manter disponível e de forma confiável, na qual só o usuário com acesso poderá acessa-lo.
Além disso, podemos pensar nas seguintes perguntas: Qual o protocolo que pretende ser utilizado é seguro? Possui criptografia? Terão que tipos de contas disponíveis na aplicação? Administrador e usuário comum? Quem poderá ter acesso? Qual ação cada usuário pode realizar? Editar? Deletar? Ler?
Na fase de design, passaremos a utilizar o Threat Modelling! Ele é conhecido como Modelagem de Ameaça e é bastante utilizado na modelagem de uma arquitetura segura. Nós temos dois modelos como principais: STRIDE e DREAD. O STRIDE categoriza de acordo com ameaças (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service e Escalation of Privilege), enquanto o DREAD categoriza os riscos de forma quantitativa, pontuando a severidade alta, média ou baixa. Vale lembrar que essa fase é muito importante, pois precisamos pensar no fluxo do dado e de que forma ele será trafegado. Ele terá interação com aplicação externa? Essa aplicação externa possui alguma vulnerabilidade? Qual versão do banco de dados será utilizado? Qual tipo de autenticação utilizada pela API?
Recomendo esse material para entenderem mais sobre esse assunto:
https://owasp.org/www-pdf-archive/AdvancedThreatModeling.pdf
Na fase de desenvolvimento, pensaremos em como podemos evitar vulnerabilidades, como descritas na OWASP TOP 10. Passaremos a validar inputs ou por exemplo, criaremos whitelists para que apenas termos conhecidos sejam passados (o que não ocorre com blacklist, você estaria limitando apenas o que você tem certeza que é vulnerável). Como também, com relação as APIs vale olhar se ela está realmente utilizando o método de autenticação, como também, se é possível alterar o método utilizado, onde deveria ser POST/ usar GET ou se o id passado na URL está de forma sequencial (lembre-se de utilizar o método uuid ou hash para evitar essa última vulnerabilidade). Aqui nas imagens abaixo, podemos ver claramente esse tipo de vulnerabilidade e sendo possível, acessar informação de outros usuários por meio da enumeração sequencial de usuário e a falta de método de autorização.
Além disso, vale também ler sobre a OWASP TOP 10, OWASP API e Code Review Guide para entender melhor sobre os temas comentados:
https://owasp.org/www-pdf-archive/OWASP_Code_Review_Guide_v2.pdf
Após isso, iremos para a fase de teste. Nessa fase, é importante fazermos o Code Review para ver se não há nenhuma vulnerabilidade que a ferramenta de SAST (Teste estático) não identificou ou até mesmo, retirar os falsos positivos que são encontrados por essas ferramentas. Deixo aqui algumas ferramentas que eu considero bem interessante nessa fase. Inclusive, têm dois orquestradores de testes estáticos que são muito bons, pois conseguem identificar as linguagens existentes nos repositórios e realizam a análise para diversas linguagens. Além disso, são open-sources e são disponibilizadas pelas empresas Globo e Zup Innovation respectivamente: Huskyci e Horusec.
Além deles, temos: SonarQube, Snyk, Depedency-check da OWASP e o próprio Bandit (esse apenas para python).
Para análise de teste dinâmico (DAST), têm duas ferramentas que considero principais: OWASP ZAP e Burp Suite (embora essa seja paga). Ambas possuem teste dinâmico para serem inseridos na pipeline de DevSecOps.
Por último, antes de colocarmos a aplicação em produção, temos algumas etapas a serem realizadas.
Pentest é bastante recomendado antes do Deployment, pois analistas de segurança poderão testar a aplicação e estressa-la ao máximo, para descobrir falhas que não puderam ser vistas nas etapas anteriores (mesmo o Secure Shift Left sendo implementado, é bastante recomendado o Pentest, principalmente em aplicações financeiras).
Como também, é muito importante o Hardening para poder fazer modificações no servidor aonde a aplicação estará hospedada. Por exemplo, atualizar serviços, reduzir portas utilizadas na aplicação ou mesmo, utilizar portas altas para que seja evitado de ser encontrado um serviço por um port scan padrão, retirar banners das aplicações (para evitar que versão da mesma seja exposta) ou aplicar o Firewall corretamente.
Dessa maneira, poderemos ter aplicações expostas à Internet de maneira segura.
Vale ressaltar também, que essas etapas explicadas anteriormente, geralmente são realizadas por Application Security Engineers, para validarem que a aplicação está sendo desenvolvida de maneira segura e testada corretamente antes de irem para produção. A fase de Pentest, geralmente é testada pelo Red Team. No entanto, Application Security Engineers também podem realizar esses testes dependendo da estrutura da empresa.
Agora, iremos falar sobre CI/CD e como o SSDLC está relacionado a esses termos :)
Acredito que essa imagem consiga demonstrar bem o que esses termos significam.
CI → Integração contínua está ligada ao processo de automação. Um exemplo disso, ocorre quando há uma nova mudança no código e testa essa mudança na sua aplicação. Para visualizarmos melhor isso, esse processo pode acontecer após ter sido feito um pull request no Github → Essa informação cria um trigger no Travis CI (uma ferramenta de CI/CD) → na qual o mesmo, cria uma nova imagem dessa sua aplicação durante o processo de build e envia essa imagem ao Docker Hub → após essa imagem criada → ela pode ser testada no ambiente de teste, utilizando DAST/SAST ou mesmo testes de qualidade ou BDD. Caso esse teste passe, poderemos lançar para o ambiente de produção (CD).
Para ilustrar:
CD → Implantação contínua está ligada ao lançamento automático (automação) de uma mudança para o ambiente de produção (ou seja o deployment).
Para ilustrar:
Vale ressaltar que algumas ferramentas de CI/CD bastante utilizadas são: Jenkins, Gitlab CI/CD e Travis CI.
Portanto, dentro do desenvolvimento de software, precisamos construir uma aplicação com segurança e de forma eficiente. Nós utilizamos a metodologia Agile para fazermos a entrega de cada release com maior qualidade, no tempo estabelecido e com todas as etapas testadas. Para isso ocorrer, precisamos cada vez mais de processos automatizados, no qual a cultura de DevSecOps consegue propor. Como também, é desenvolvida uma pipeline segura com todas essas integrações e na qual consegue garantir a segurança no processo de ponta a ponta.
Espero que dessa maneira, tenha se tornado claro o uso desses termos que temos visto cada vez mais ultimamente. Como também, entender o papel do Application Security Engineer :)