Skip to content
Latchkey

O que é teste de fuzz?

O teste de fuzz lança grandes quantidades de entradas aleatórias, malformadas ou inesperadas em um programa para encontrar travamentos, congelamentos e falhas de segurança.

O teste de fuzz, ou fuzzing, é a prática de bombardear o código com entradas de lixo para ver o que quebra. Enquanto o teste baseado em propriedades verifica propriedades lógicas, o fuzzing busca principalmente a entrada que faz um programa travar, congelar ou se comportar mal. É um pilar dos testes de segurança para parsers, decodificadores e qualquer coisa que lide com dados não confiáveis.

Como o fuzzing funciona

Um fuzzer alimenta o alvo com um fluxo de entradas geradas e observa resultados ruins: travamentos, erros de memória, loops infinitos ou falhas de asserção. Cada falha interessante é salva como um caso reproduzível. Quanto mais entradas ele tenta, mais fundo ele alcança nos casos extremos.

Fuzzing guiado por cobertura

Os fuzzers modernos são guiados por cobertura: eles instrumentam o código e favorecem entradas que alcançam novos caminhos de código, evoluindo em direção a entradas que exercitam mais partes do programa. Isso os torna muito mais eficazes do que entradas aleatórias cegas para encontrar bugs profundos.

Um exemplo rápido

Um alvo de fuzz entrega bytes arbitrários a um parser; o harness falha se o parser algum dia travar com uma entrada que deveria rejeitar graciosamente.

A Go fuzz target
func FuzzParse(f *testing.F) {
  f.Fuzz(func(t *testing.T, data []byte) {
    Parse(data) // must not panic
  })
}

Onde o fuzzing compensa

  • Parsers, decodificadores e serializadores.
  • Qualquer coisa que processe entradas externas não confiáveis.
  • Caminhos de código sensíveis à segurança.
  • Encontrar travamentos que os exemplos nunca disparam.

Fuzzing em CI

O fuzzing é aberto, então as equipes geralmente executam uma passagem curta de fuzz em cada pull request e fuzzing contínuo mais longo de forma agendada. Ambos se beneficiam de execuções paralelas em runners rápidos, já que mais poder de computação significa mais entradas testadas e mais bugs encontrados por hora.

Principais conclusões

  • O teste de fuzz alimenta o programa com entradas aleatórias ou malformadas para encontrar travamentos e falhas.
  • Fuzzers guiados por cobertura evoluem as entradas em direção a novos caminhos de código.
  • Execute fuzzing curto por PR e fuzzing agendado mais longo em CI.

Guias relacionados