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.

Autor
Interpretica
Publicado
Leitura
9 min
Temas
security, vulnerabilities, static analysis, embedded systems

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.