Porque é difícil detetar vulnerabilidades em sistemas complexos (e como abordar o problema)
Em sistemas complexos, as vulnerabilidades raramente são bugs isolados. Surgem de interações, da temporização e das condições reais. Saiba como a análise estática e os testes ao nível do sistema ajudam a detetá-las.

Os sistemas de software modernos são cada vez mais complexos. Por isso, também são mais difíceis de proteger.
Muitas vezes, as vulnerabilidades não são óbvias. Não são simples bugs num pedaço de código isolado. Surgem da interação entre componentes, de estados inesperados e de pressupostos que falham em condições reais.
Isso torna-as muito mais difíceis de detetar.
As vulnerabilidades nem sempre estão onde se espera
Na visão tradicional da segurança, as vulnerabilidades são muitas vezes tratadas como problemas isolados:
uma validação em falta
uma chamada de função insegura
um endpoint exposto
Mas, em sistemas complexos e embebidos, muitas vulnerabilidades não estão ligadas a uma única linha de código.
Aparecem quando:
vários componentes interagem
a temporização afeta o comportamento
as dependências criam estados inesperados
as condições reais diferem dos ambientes de teste
É por isso que um sistema pode passar nos testes e, mesmo assim, falhar em produção.
Porque não chegam as abordagens tradicionais
Muitas equipas usam uma combinação de:
testes funcionais
testes de intrusão
revisão manual de código
Estas abordagens são importantes, mas têm limites.
Testes funcionais
Validam cenários específicos, mas não conseguem cobrir todos os caminhos de execução possíveis.
Testes de intrusão
Focam-se em padrões de ataque conhecidos e deixam escapar as vulnerabilidades que não encaixam neles.
Revisão de código
Depende da atenção e do contexto de quem revê. Não escala para bases de código grandes.
Nenhuma destas abordagens mostra por completo como um sistema se comporta em todos os caminhos de execução possíveis.
A distância entre o código e o comportamento
Um dos maiores desafios da cibersegurança é a distância entre o que o código deve fazer e o que o sistema faz na realidade.
Essa distância aumenta em:
sistemas distribuídos
ambientes embebidos
sistemas com dependências complexas
É muitas vezes nessa distância que estão as vulnerabilidades. Não se veem no código isolado. Os testes habituais não as ativam. Só aparecem em condições específicas.
Outra abordagem: análise + testes em condições reais
Para detetar este tipo de vulnerabilidades, é preciso outra abordagem.
Análise estática
A análise estática de código ajuda a identificar cedo possíveis riscos de segurança, antes de o sistema correr.
- uso inseguro da memória
- caminhos de execução arriscados
- dependências ocultas
- violações das práticas de programação segura
Mostra o que pode correr mal.
Testes ao nível do sistema
Os testes de segurança ao nível do sistema revelam como o software se comporta em condições reais.
- interações entre componentes
- problemas de temporização
- comportamento inesperado em execução
Mostram o que corre mal na realidade.
Porque contam as duas
Depender de uma só abordagem deixa pontos cegos.
A análise estática pode detetar riscos de segurança que os testes nunca ativam.
Os testes de segurança podem revelar falhas que não são óbvias no código.
Em conjunto, dão uma visão mais completa da segurança do sistema.
Onde isto conta mais
Esta abordagem é especialmente importante em:
Sistemas embebidos
Ambientes que dependem do hardware, onde as falhas são caras e difíceis de reproduzir.
Ambientes de rede
Sistemas com caminhos de comunicação complexos e um comportamento que depende do hardware.
Sistemas distribuídos de grande escala
Bases de código com demasiadas interações entre componentes para as testar manualmente.
Aplicações críticas para a segurança funcional (safety)
Sistemas onde uma vulnerabilidade pode ter consequências graves no mundo real.
Uma forma prática de pensar a segurança
Em vez de tratar a segurança como uma camada à parte, ajuda pensar nela como uma propriedade do comportamento do sistema.
Ter código correto é só a primeira questão. As outras são:
Como se comporta o sistema em condições reais?
Onde pode falhar de forma inesperada?
Em que pressupostos assenta?
Responder a estas perguntas exige análise e testes.
Conclusão
As vulnerabilidades em sistemas complexos são difíceis de detetar porque não são problemas isolados.
Surgem das interações, da temporização e das condições reais.
Para as tratar, as equipas precisam de mais do que testes tradicionais ou análises isoladas. Precisam de uma abordagem combinada, que olhe para o código e para o comportamento e reduza a distância entre os dois.