Defenda sua casa: modelagem de ameaças no mundo real – parte 2 de 3

Escrito por  Lucas William, Thiago Bispo

Introdução

Na primeira parte do artigo sobre modelagem de ameaças, concentramos nossos esforços na fundamentação teórica, abordando o desenvolvimento e as metodologias distintas. Agora, nesta segunda parte do artigo sobre modelagem de ameaças vamos demonstrar de forma prática como modelar ameaças em uma aplicação, bem como os requisitos de segurança para evitar que essas ameaças se transformem em vulnerabilidades.

Para aplicar a modelagem na prática, utilizaremos como exemplo uma aplicação de Capture The Flag (CTF) hospedada na plataforma Hacking Club. A máquina “Stonks” representa um cenário de uma aplicação que cria dashboards de portfólios pessoais de investimento, realizando consultas em uma API externa. Isso permite a realização de uma modelagem de ameaça completa voltada a um cenário real, bem como o exercício posterior que consiste em realizar os testes de requisitos de segurança. Nesse caso, a aplicação já está desenvolvida, “em produção”, então iremos mostrar como poderíamos evitar as vulnerabilidades que ela apresenta se passasse por um processo de modelagem de ameaças adequado. Iremos criar a modelagem a partir de 4 perguntas, de acordo com o Manifesto de Modelagem de Ameaças:

  1. No que estamos trabalhando?
  2. O que poderia dar errado?
  3. O que faremos sobre isso?
  4. Fizemos um trabalho bom e suficiente?

No que estamos trabalhando?

Entendendo a Aplicação

Abaixo são listadas as informações que temos sobre a aplicação:

  • Tecnologias:
    • VueJS no front-end
    • PHP Laravel 11.0 no backend
  • API externa utilizada:
    • Yahoo Finance

Para entender todo o cenário de uma forma mais clara, precisamos do desenho da arquitetura da aplicação com as tecnologias utilizadas. Isso pode ser fornecido pela equipe de arquitetura ou podemos realizar em conjunto com o time de negócios quando não há um desenho ainda. A Figura 1 mostra o desenho de arquitetura de alto nível da aplicação que será avaliada:

Figura 1 – Desenho da arquitetura da aplicação em alto nível

Como mostrado no desenho de arquitetura, podemos identificar todo o fluxo da aplicação, desde a interação do usuário até as solicitações feitas para um sistema externo. O usuário acessa a aplicação através de um site, onde pode se registrar e autenticar. A aplicação está hospedada na AWS, utiliza PHP como linguagem principal no backend e suas principais funcionalidades são a tela de login, de registro e o dashboard de investimentos. Os dados dos usuários são armazenados em um banco de dados MySQL, e a aplicação se comunica com uma API de microsserviços, que, por sua vez, obtém informações sobre os ativos de investimento através do Yahoo Finance. Com toda essa estrutura em mãos, começamos a mapear os ativos, dando início à nossa modelagem de ameaças.

O que poderia dar errado? 

Identificando Ativos

Para dar vida à modelagem de ameaças, começamos identificando e pontuando elementos essenciais nos diagramas, iniciando pelos ativos. 

Na modelagem de ameaças, como visto na primeira parte do artigo, os ativos representam os elementos importantes que necessitam de proteção contra ataques. Eles incluem desde informações sensíveis, como dados pessoais de clientes, até sistemas de TI, como infraestrutura física. Cada ativo possui um valor específico e, se comprometido, pode causar danos graves à empresa, como perda financeira ou vazamento de dados. Identificar os ativos é um dos primeiros passos para avaliar as ameaças e as vulnerabilidades, assim temos ideia do que vamos começar avaliar, garantindo que as medidas de segurança sejam focadas no que é mais importante para o negócio.

No intuito de mapear os ativos, podemos imaginar uma casa que contém objetos valiosos, como eletrônicos, jóias e outros itens de grande importância. Nesse contexto, os ativos são representados por esses itens de valor, que precisam ser protegidos para evitar que sejam roubados ou comprometidos.

Tendo uma visão clara de mapeamento de ativos, começamos a listar e posicionar os ativos da nossa infraestrutura como descrito abaixo:

Figura 2 – Mapeando os ativos que percorrem o fluxo de dados na aplicação

Cada caixinha verde representa um ativo dentro da arquitetura, que estão evidenciados na Figura 3.

Figura 3 – Ativos mapeados na aplicação

Os ativos destacados em nossa modelagem são classificados como de alta prioridade. Por isso, devem receber atenção na implementação de controles de segurança, assegurando a proteção contra possíveis ameaças. 

Para facilitar a identificação e o acompanhamento, cada ativo será designado por uma sigla no formato A01, A02, e assim por diante.

  • A01 – Credenciais de autenticação
  • A02 – Dados cadastrais do usuário
  • A03 – Credenciais do banco de dados
  • A04 – Informações de investimentos e financeiras 
  • A05 – Registros de transações na bolsa de valores

Modelando as Ameaças

Mapeamos todos os ativos de nossa infraestrutura. Agora, vamos começar a identificar as ameaças usando a analogia da casa. Como um invasor poderia acessar esta casa para roubar os itens valiosos? Ele poderia, por exemplo, utilizar uma cópia da chave para abrir a porta. Caso a porta esteja destrancada, ele pode entrar na residência ou até mesmo pular a janela. Essa lógica nos ajuda a visualizar como as ameaças de vulnerabilidades permitem acesso não autorizado aos ativos e ao ambiente e causar diversos problemas.

Com base nessa analogia, agora vamos mapear as ameaças em nossa infraestrutura, analisando cada ativo identificado previamente. Na Figura 4 podemos observar as ameaças mapeadas na aplicação.

Figura 4 – Ameaças mapeadas na aplicação

Toda a nossa estrutura foi mapeada, associando possíveis ameaças a cada ativo identificado anteriormente. Para facilitar a identificação, cada ameaça será designada com a sigla “T”, sendo enumerada sequencialmente como T01, T02 e assim por diante.

As ameaças foram mapeadas da seguinte forma:

  • T01 – Injeção SQL: um atacante poderia adulterar consultas no banco de dados para consultar dados sensíveis e de outros usuários.
  • T02 – Ataque de força bruta: um atacante poderia tentar acessar uma conta ou servidor através da tentativa e erro, usando combinações de senhas e nomes de usuário até encontrar a correta.
  • T03 – Contorno de autenticação: um atacante poderia  acessar funcionalidades ou dados sem autenticação, manipulando parâmetros, explorando endpoints desprotegidos ou reutilizando tokens inválidos.
  • T04 – Autorização quebrada a nível de objeto: um atacante poderia acessar, modificar ou excluir objetos que pertencem a outros usuários, manipulando identificadores de recursos (como IDs) em requisições ou explorando falhas na verificação de permissões.
  • T05 – Enumeração de usuários: um atacante poderia  identificar usuários válidos ou inválidos com base nas respostas da aplicação, como mensagens de erro diferenciadas, tempos de resposta variados ou outros comportamentos que revelem a existência de contas.
  • T06 – Cross-site Scripting (XSS): um atacante poderia  injetar scripts maliciosos em páginas web que são visualizadas por outros usuários, permitindo roubo de cookies, redirecionamento de usuários, execução de ações em nome da vítima, ou exfiltração de dados sensíveis.
  • T07 – Sequestro de sessão: um atacante poderia roubar ou sequestrar uma sessão ativa de outro usuário, utilizando técnicas como interceptação de cookies de sessão, exploração de falhas em tokens de autenticação, ou manipulando parâmetros de sessão para se passar por outro usuário.
  • T08 – Ataque de phishing: um atacante poderia enganar usuários para que forneçam informações sensíveis, como credenciais, através de mensagens fraudulentas, e-mails ou sites falsificados que imitam fontes confiáveis.
  • T09 – Server-side Request Forgery (SSRF): um atacante poderia manipular a aplicação para fazer requisições HTTP a recursos internos ou externos que a aplicação não deveria acessar, explorando falhas na validação de entradas e podendo, por exemplo, obter informações confidenciais ou realizar ataques a sistemas internos.
  • T10 – Autorização quebrada a nível de função: um atacante poderia acessar ou executar funções restritas a usuários com privilégios mais altos, manipulando parâmetros ou aproveitando falhas na verificação de permissões, permitindo-lhe realizar ações que deveriam ser restritas a administradores ou usuários com permissões específicas.

Ao concluir o mapeamento das ameaças em nossa estrutura, é possível observar que nossos ativos estarão vulneráveis a diversos problemas, caso não sejam implementados mecanismos de proteção adequados para mitigá-los. Sendo assim, o próximo passo é descrever os controles e os requisitos de segurança para que as ameaças não se concretizem.

Classificando as ameaças

Com a definição das ameaças, podemos classificá-las de acordo com as categorias STRIDE, com o objetivo de entender o tipo de ameaça e propor os controles adequados posteriormente. A Tabela 1 apresenta a classificação das ameaças.

ID Ameaça Categoria STRIDE
T01 Injeção SQL Adulteração
T02 Ataque de força bruta Negação de serviço
T03 Contorno de autenticação Falsificação
T04 Autorização quebrada a nível de objeto Elevação de privilégio
T05 Enumeração de usuários Repúdio
T06 Cross-site Scripting (XSS) Adulteração
T07 Sequestro de sessão  Elevação de privilégio
T08 Ataque de phishing Falsificação
T09 Server Side Request Forgery Falsificação
T10 Autorização quebrada a nível de função Elevação de privilégio

Tabela 1 – Classificação das ameaças de acordo com a categoria STRIDE

Atribuindo as severidades

Após mapear todas as ameaças em nossa estrutura e classificá-las, podemos atribuir notas de severidade de acordo com o CVSS.

ID Ameaça Categoria STRIDE CVSS 4.0
T01 Injeção SQL Adulteração 7.0
T02 Ataque de força bruta Negação de serviço 6.3
T03 Contorno de autenticação Falsificação 8.9
T04 Autorização quebrada a nível de objeto Elevação de privilégio 6.3
T05 Enumeração de usuários Repúdio 8.2
T06 Cross-site Scripting (XSS) Adulteração 3.1
T07 Sequestro de sessão Elevação de privilégio 7.1
T08 Ataque de phishing Falsificação 4.2
T09 Server Side Request Forgery Falsificação 8.9
T10 Autorização quebrada a nível de função Elevação de privilégio 8.7

Tabela 2 – Classificação das ameaças de acordo com as categorias do framework STRIDE

O que faremos sobre isso?

Definindo requisitos e controles de segurança

Os requisitos de controle representam os mecanismos de segurança que devem ser implementados em nossos ativos para protegê-los das ameaças identificadas anteriormente. 

Usando a analogia da casa, para proteger nossos bens mais valiosos, podemos adotar diversos métodos de segurança, como instalar câmeras com alarmes para alertar as autoridades em caso de invasão, trancar portas e janelas, e implementar outras medidas de proteção contra acessos não autorizados.

Assim como é essencial pensar como um bom atacante para identificar possíveis ameaças, também é importante agir como um defensor habilidoso, projetando e aplicando pontos de controle que abordem todas as ameaças presentes na estrutura. E para definir controles eficazes contra as ameaças, é necessário conhecer como os ataques funcionam, ou seja, através da mentalidade ofensiva. Além disso, para definir os controles podemos utilizar para referência frameworks como OWASP ASVS, CIS Controls e NIST SCF. A Figura 5 demonstra os controles propostos em nossa modelagem de ameaça.

Figura 5 – Controles posicionados no desenho da aplicação

A Tabela 3 contém os controles recomendados de acordo com os cenários de ameaça previstos.

ID Control
C01 Filtro de entrada de dados do usuário
C02 Rate limiting
C03 Controle de acesso robusto
C04 Mensagem de erro genérica
C05 Multi-fator de autenticação
C06 Invalidação de sessão
C07 Validação de URL no backend
C08 Criptografia de dados em repouso

Tabela 3 – Controles recomendados para o presente cenário de ameaças

C01 – Parametrização de Consulta:

  • Garantir que caracteres especiais em dados de entrada sejam escapados corretamente para evitar injeções de código malicioso;
  • Escapar caracteres especiais em consultas e comandos para proteger contra ataques de injeção em bancos de dados e outros sistemas.
  • Assegurar a autenticidade e integridade das comunicações, prevenindo manipulações não autorizadas durante a troca de informações.

C02 – Rate Limit:

  • Implementar rate limit para restringir o número de solicitações que podem ser feitas em um determinado período de tempo;
  • Monitorar e registrar as solicitações para identificar atividades suspeitas ou maliciosas;
  • Implementar limites diferenciados com base em diferentes tipos de solicitações ou usuários.

C03 – Controle de acesso robusto: 

  • Definir papéis e permissões claras para os usuários com base em suas responsabilidades e funções na organização, garantindo que apenas usuários autorizados tenham acesso aos recursos críticos.
  • Exigir múltiplos fatores de autenticação, como senha, token ou biometria, para melhorar a segurança e garantir que o acesso seja concedido apenas aos usuários legítimos.
  • Garantir que as sessões de usuário sejam adequadamente gerenciadas, com expiração automática após períodos de inatividade, e fornecendo a possibilidade de revogar sessões ativas caso haja suspeita de acesso não autorizado.

C04 – Mensagem de erro genérica:

  • Certificar-se de que erros não revelem informações sobre a configuração do sistema, como detalhes do ambiente, chaves de API ou credenciais de banco de dados.
  • Utilizar um padrão de mensagens de erro que informe o usuário de forma clara que algo deu errado, sem fornecer informações que possam ser exploradas. Por exemplo, “Falha ao processar sua solicitação. Por favor, tente novamente mais tarde.”
  • Ao fornecer APIs, as respostas de erro devem ser padronizadas, com códigos HTTP adequados (ex.: 400 para erro de solicitação, 500 para erro interno do servidor) e sem detalhes técnicos que possam ser usados maliciosamente.

C05 – Multi-fator de autenticação:

  • Garantir que todos os sistemas e contas que lidam com dados sensíveis ou oferecem acesso a recursos críticos utilizem a autenticação multifatorial. Isso inclui contas de usuários, administradores e acesso a APIs.
  • Além da autenticação inicial, exigir MFA para operações de alto risco, como transações financeiras, alteração de configurações de segurança ou modificação de dados críticos.
  • Implementar verificações periódicas de MFA para sessões de longa duração, ou para atividades suspeitas, como login de um novo dispositivo ou localização geográfica diferente.

C06 – Invalidação de sessão:

  • Implementar a expiração automática das sessões de usuário após um período de inatividade definido. Isso ajuda a minimizar o risco de acesso não autorizado caso o usuário se esqueça de sair de sua conta ou deixe seu dispositivo desprotegido.
  • Garantir que, ao realizar o logout, todos os tokens de sessão e identificadores de sessão sejam invalidados corretamente no servidor, de modo que a sessão não possa ser reutilizada ou restaurada.
  • Sempre que o usuário alterar suas credenciais (como senha ou e-mail), todas as sessões ativas relacionadas ao usuário devem ser invalidadas, forçando o re-login para garantir a segurança.

C07 – Validação de URL no backend:

  • Garantir que as URLs fornecidas sejam validadas contra uma lista de domínios confiáveis antes de serem processadas pelo backend. URLs fora dessa lista devem ser rejeitadas.
  • Restringir o backend de acessar endereços locais ou privados, como localhost ou 127.0.0.1, para evitar a exploração de recursos internos por meio de requisições maliciosas.
  • Garantir que o backend registre todas as requisições relacionadas a URLs externas, possibilitando auditorias e identificação de possíveis tentativas de abuso.

C08 – Criptografia de dados em repouso:

  • Usar chaves de criptografia armazenadas de forma segura, separadas do sistema que acessa os dados, para evitar exposição acidental ou roubo das chaves.
  • Implementar criptografia em discos e dispositivos de armazenamento (Full Disk Encryption) para proteger dados em caso de roubo ou perda física do hardware.
  • Adotar a prática de rotação periódica das chaves de criptografia, minimizando o impacto caso uma chave seja comprometida.

Ao apresentar a modelagem de ameaças como um todo para o time de desenvolvimento, é importante que eles entendam os controles e onde devem ser implementados. Para acompanhamento desse processo, é possível estabelecer um checklist com os três requisitos de cada controle, e, com isso, permitir que o desenvolvedor confirme os controles já desenvolvidos.  A Tabela 4 apresenta um checklist simples, em que a coluna de “Status” poderia ser utilizada para acompanhamento da implantação dos controles.

 

ID Controle Requisitos Status
C01 Parametrização de Consulta Garantir que caracteres especiais em dados de entrada sejam escapados corretamente para evitar injeções de código malicioso. Não implementado
Escapar caracteres especiais em consultas e comandos para proteger contra ataques de injeção em bancos de dados e outros sistemas. Não implementado
Assegurar a autenticidade e integridade das comunicações, prevenindo manipulações não autorizadas durante a troca de informações. Não implementado
C02 Rate Limit Implementar rate limit para restringir o número de solicitações que podem ser feitas em um determinado período de tempo Não implementado
Monitorar e registrar as solicitações para identificar atividades suspeitas ou maliciosas Não implementado
Implementar limites diferenciados com base em diferentes tipos de solicitações ou usuários Não implementado
C03 Controle de acesso robusto Definir papéis e permissões claras para os usuários com base em suas responsabilidades e funções na organização, garantindo que apenas usuários autorizados tenham acesso aos recursos críticos. Não implementado
Exigir múltiplos fatores de autenticação, como senha, token ou biometria, para melhorar a segurança e garantir que o acesso seja concedido apenas aos usuários legítimos. Não implementado
Garantir que as sessões de usuário sejam adequadamente gerenciadas, com expiração automática após períodos de inatividade, e fornecendo a possibilidade de revogar sessões ativas caso haja suspeita de acesso não autorizado. Não implementado
C04 Mensagem de erro genérica Certificar-se de que erros não revelem informações sobre a configuração do sistema, como detalhes do ambiente, chaves de API ou credenciais de banco de dados. Não implementado
Utilizar um padrão de mensagens de erro que informe o usuário de forma clara que algo deu errado, sem fornecer informações que possam ser exploradas. Por exemplo, “Falha ao processar sua solicitação. Por favor, tente novamente mais tarde.” Não implementado
Ao fornecer APIs, as respostas de erro devem ser padronizadas, com códigos HTTP adequados (ex.: 400 para erro de solicitação, 500 para erro interno do servidor) e sem detalhes técnicos que possam ser usados maliciosamente. Não implementado
C05 Multi-fator de autenticação Garantir que todos os sistemas e contas que lidam com dados sensíveis ou oferecem acesso a recursos críticos utilizem a autenticação multifatorial. Isso inclui contas de usuários, administradores e acesso a APIs. Não implementado
Além da autenticação inicial, exigir MFA para operações de alto risco, como transações financeiras, alteração de configurações de segurança ou modificação de dados críticos. Não implementado
Implementar verificações periódicas de MFA para sessões de longa duração, ou para atividades suspeitas, como login de um novo dispositivo ou localização geográfica diferente. Não implementado
C06 Invalidação de sessão Implementar a expiração automática das sessões de usuário após um período de inatividade definido. Isso ajuda a minimizar o risco de acesso não autorizado caso o usuário se esqueça de sair de sua conta ou deixe seu dispositivo desprotegido. Não implementado
Garantir que, ao realizar o logout, todos os tokens de sessão e identificadores de sessão sejam invalidados corretamente no servidor, de modo que a sessão não possa ser reutilizada ou restaurada. Não implementado
Sempre que o usuário alterar suas credenciais (como senha ou e-mail), todas as sessões ativas relacionadas ao usuário devem ser invalidadas, forçando o re-login para garantir a segurança. Não implementado
C07 Validação de URL no backend Garantir que as URLs fornecidas sejam validadas contra uma lista de domínios confiáveis antes de serem processadas pelo backend. URLs fora dessa lista devem ser rejeitadas. Não implementado
Restringir o backend de acessar endereços locais ou privados, como localhost ou 127.0.0.1, para evitar a exploração de recursos internos por meio de requisições maliciosas. Não implementado
Garantir que o backend registre todas as requisições relacionadas a URLs externas, possibilitando auditorias e identificação de possíveis tentativas de abuso. Não implementado
C08 Criptografia de dados em repouso Usar chaves de criptografia armazenadas de forma segura, separadas do sistema que acessa os dados, para evitar exposição acidental ou roubo das chaves. Não implementado
Implementar criptografia em discos e dispositivos de armazenamento (Full Disk Encryption) para proteger dados em caso de roubo ou perda física do hardware. Não implementado
Adotar a prática de rotação periódica das chaves de criptografia, minimizando o impacto caso uma chave seja comprometida. Não implementado

Tabela 4 – Checklist de controles

Conclusão

Ao final do processo temos uma modelagem de ameaças completa e com os controles estabelecidos. Para facilitar o processo de implementação deles, criamos o checklist com o que o desenvolvedor deve implementar. 

Porém, depois de todo esse processo, ainda não temos a certeza se a modelagem de ameaças e os controles são suficientes para proteger a aplicação e, com isso, nos vem à mente a última pergunta do manifesto que trouxemos lá na introdução: Será que fizemos um bom trabalho? Responderemos ela na terceira e última parte deste artigo, através dos testes dos requisitos em que iremos prontamente atacar a aplicação, buscando validar esses controles e até encontrar pontos adicionais que podem ter ficado de fora da modelagem de ameaças.

Logo da Hakai.