O bug no nosso scanner de segredos que os canários não encontraram
Envio
Antes de qualquer kit que vendemos ser compactado, um portão o escaneia em busca dos valores reais dos nossos próprios segredos. Cada varredura começa plantando canários, um de cada tipo, e se recusa a rodar a menos que capture todos eles. Sempre os capturava. Ainda assim, havia um bug.
Como o portão lê os segredos
O portão não procura apenas por coisas com formato de chaves. Ele lê os arquivos onde nossos segredos residem (arquivos env, configurações JSON, arquivos de chave), pega todos os valores cujo nome indica que são segredos e então busca no que estamos prestes a enviar exatamente esses valores, como escritos e codificados em base64.
O bug
Para uma linha como esta:
DB_PASSWORD='Tr0ub4dor-and-3' # rotacionada em maio
o leitor removia as aspas ao redor apenas quando o valor começava e terminava com um caractere de aspas. Com um comentário após o valor, a linha termina em uma letra, então as aspas permaneciam. O comentário era cortado em seguida, e o portão continuava a buscar por 'Tr0ub4dor-and-3', com as aspas incluídas. Um kit contendo a senha sem essas aspas teria passado.
Por que os canários nunca notaram
Um canário testa uma rede: plante um valor que o scanner já conhece, verifique se ele é encontrado. Nossos valores de canário eram entregues diretamente ao scanner, então nunca passavam pelo código que lê uma linha de configuração. Todas as redes eram testadas, mas o parser à frente delas não era.
Como encontramos
Estávamos transformando o portão em um produto próprio e escrevemos um teste que o alimentava com um arquivo de configuração nos formatos que as pessoas realmente escrevem: export, aspas, comentários no final. O teste falhou na linha com aspas e comentário. A correção lê um valor entre aspas até sua aspas de fechamento e ignora o que vier depois.
Isso importava?
Verificamos antes de mudar qualquer coisa. Na nossa máquina de build, o portão lê 133 valores de segredo dos 59 arquivos que lhe são fornecidos, e em uma segunda máquina 499; nenhum tinha esse formato. Nenhuma veredito anterior muda: todos os kits que lançamos foram escaneados pelos mesmos valores que seriam escaneados agora. Corrigimos o portão nas três máquinas de qualquer forma.
A conclusão
Se um scanner extrai aquilo que procura, teste a extração com entradas realistas, e não apenas a pesquisa com valores plantados. Um canário prova que a rede funciona; não diz nada sobre se os peixes certos chegam até ela. Os testes do Secret Gate agora cobrem ambos os casos, e antes do seu lançamento verificámos que ele lê exatamente os mesmos 133 valores que o nosso portão de build.