Os diagramas de arquitetura costumam ser desenhados para explicar como um sistema funciona. Isso é útil, mas não é a pergunta que uma revisão de segurança faz. Uma revisão pergunta onde muda a confiança: onde um pedido de alguém que não controla chega a algo que lhe importa.
A boa notícia é que consegue responder a essa pergunta numa única página. O diagrama não precisa de ser bonito nem completo. Precisa de mostrar as fronteiras e cada seta que as atravessa.
O que conta como fronteira de confiança
Uma trust boundary é qualquer ponto onde dados ou controlo passam entre duas partes com privilégios diferentes ou controladas por pessoas diferentes. Algumas são óbvias, como a fronteira com a internet. Muitas não são:
- Entre o browser e a sua API, porque o browser pertence ao utilizador.
- Entre tenants na mesma base de dados, porque um cliente não pode ler os dados de outro.
- Entre o seu serviço e um webhook de terceiros, porque quem envia é outra pessoa.
- Entre o runner de CI e a produção, porque o runner executa código de pull requests.
- Entre uma ferramenta de suporte e os dados dos clientes, porque o acesso dos colaboradores é um privilégio por si só.
- Entre um agente de IA e as ferramentas que pode chamar, porque o prompt pode vir de conteúdo não confiável.
Se só desenhar a primeira, a revisão só vai encontrar problemas na primeira.
Cinco tipos de caixa
Mantenha a notação pequena. Usamos cinco formas, que correspondem mais ou menos aos elementos de um diagrama de fluxo de dados clássico:
| Forma | Significa | Exemplo |
|---|---|---|
| Pessoa | Um ator humano | Cliente, admin, agente de suporte |
| Caixa | Algo que se executa | API, worker, painel de administração |
| Cilindro | Algo que guarda dados | Base de dados, bucket, fila |
| Cloud | Algo que não é corrido por si | Fornecedor de pagamentos, fornecedor de identidade, API SaaS |
| Linha tracejada | Uma trust boundary | Limite da internet, fronteira entre tenants, CI para prod |
As setas mostram o fluxo de dados e apontam na direção em que o pedido viaja. Identifique cada seta com o protocolo e o que transporta: HTTPS, JSON, invoice ids. É essa etiqueta que transforma o desenho em algo que se pode rever.
Anatomia de uma fronteira esquecida
A maioria dos achados de revisão segue o mesmo padrão. Existe uma fronteira, ninguém a desenhou, por isso ninguém fez as perguntas que vêm com ela. Um exemplo comum é um painel de administração interno que se assumiu ser seguro por estar "dentro":
- PressupostoO painel de administração é interno, por isso salta as verificações de autorização por objeto.
- ExposiçãoÉ acessível a partir da rede corporativa ou de uma VPN partilhada por muitas pessoas e dispositivos.
- Ponto de entradaUm portátil de um colaborador ou uma credencial partilhada é comprometido.
- ImpactoO atacante lê ou edita qualquer registo de cliente através de uma ferramenta que confiava na sua localização de rede.
Desenhar uma linha tracejada entre "staff" e "painel de admin" obriga a fazer a pergunta que o design saltou: como é que este serviço sabe quem está a chamar, e em que é que pode mexer?
As perguntas para cada seta que atravessa
Com as fronteiras desenhadas, vá seta a seta. Para cada seta que atravessa uma linha tracejada, escreva respostas curtas a estas perguntas. O STRIDE é uma lista de pistas útil aqui:
- Spoofing. Como é autenticado o chamador? Token, mTLS, assinatura, nada?
- Tampering. O input é validado do lado de quem recebe, e não apenas do lado de quem envia?
- Repúdio. A chamada fica registada com quem a fez?
- Divulgação de informação. A resposta contém mais do que o chamador devia ver?
- Negação de serviço. Há um limite de taxa, tamanho ou custo?
- Elevação de privilégios. O chamador consegue chegar a ações acima da sua função?
As respostas em branco são a sua lista de achados. Na prática, as células vazias concentram-se em duas ou três setas, e é aí que o tempo de revisão deve ir.
Manter a página atualizada
Um diagrama desenhado uma vez para uma revisão fica desatualizado em menos de um trimestre. Dois hábitos mantêm-no honesto:
- Guardar como código. Um formato de texto como Mermaid ou PlantUML no repositório faz com que as alterações apareçam nos pull requests ao lado do código que as causou.
- Ligar à mudança. Uma nova integração externa, um novo data store ou uma nova função são motivo para atualizar a página. Ponha isso no template de pull request.
Um pequeno esboço em Mermaid chega para começar:
flowchart LR
user([Customer]) -->|HTTPS, JSON| api[API]
subgraph tenant [Tenant boundary]
api -->|SQL, row-level filter| db[(Postgres)]
end
psp((Payment provider)) -->|Signed webhook| api
ci[CI runner] -.->|Deploy token| api
Verifique o seu em 10 minutos
- Abra o seu diagrama de arquitetura atual. Conte as linhas tracejadas. Se não houver nenhuma, comece por aí.
- Adicione uma boundary para ferramentas internas, CI para produção e cada callback de terceiros.
- Escolha as três setas que atravessam a fronteira mais sensível e responda às seis perguntas.
- Qualquer resposta em branco passa a ticket, ou a tema para um revisão de arquitetura.
Onde isto fica na linha
Na torre (em desenvolvimento):