# Reflections on Trusting Trust: a palestra de 1984 que previu todo ataque de cadeia de suprimento desde então

> Ken Thompson usou sua palestra do Prêmio Turing para explicar que pusera uma porta dos fundos no compilador C que se reinseria toda vez que o compilador era reconstruído - e depois apagou a evidência do código-fonte. Ler o fonte nunca acharia aquilo. Quarenta e dois anos depois existe exatamente um método que o derrota formalmente, e a razão de o XZ Utils e a 3CX terem funcionado é que quase ninguém o usa.

Source: https://ronutz.com/pt-BR/learn/reflections-on-trusting-trust  
Updated: 2026-09-08

---

## O discurso de agradecimento mais alarmante da computação

Ken Thompson e Dennis Ritchie receberam o Prêmio Turing de 1983 pelo Unix. Quem faz a palestra Turing costuma refletir sobre uma carreira. A de Thompson, publicada na Communications of the ACM em agosto de 1984, começa dizendo que ele sente estar recebendo a honraria tanto por oportunidade e acaso quanto por mérito técnico - e então descreve, em poucas páginas, um jeito de comprometer todo programa de um sistema que nenhuma revisão de código-fonte conseguiria detectar.

Ele o construiu em três estágios, e o terceiro é o que importa.

**O primeiro estágio** é um programa que imprime o próprio código-fonte. É uma velha curiosidade de programação e não faz mal nenhum; está na palestra para estabelecer que um programa pode conter uma descrição completa de si mesmo.

**O segundo estágio** é um compilador ensinado a reconhecer um trecho específico de código-fonte - o programa `login` - e, ao vê-lo, compilar junto uma porta dos fundos que aceita uma senha escolhida por Thompson. Quem lesse o fonte do `login` não acharia nada, porque não há nada lá. A porta é acrescentada durante a compilação.

**O terceiro estágio** é o movimento que a torna permanente. O compilador também é ensinado a reconhecer **quando está compilando a si mesmo**, e a reinserir os dois truques - a porta no `login` e o autorreconhecimento - no novo binário de compilador que produz.

Uma vez que esse compilador exista como binário, o fonte malicioso pode ser apagado. Dali em diante o fonte do compilador é limpo e sempre será. Toda vez que alguém reconstruir o compilador a partir desse fonte limpo, usando o compilador existente, o novo binário é infectado de novo. O defeito mora no binário, é invisível em toda listagem de fonte, e é passado adiante indefinidamente.

A moral do próprio Thompson é a frase que todo mundo cita: não se pode confiar em código que você não criou inteiramente. O parêntese dele é o que as pessoas esquecem, e é melhor - especialmente código de empresas que empregam gente como eu.

## Ele fez isso de verdade?

Fez, no sentido de que escreveu; chamou aquilo do programa mais gracinha que já escreveu. Se chegou a escapar é pergunta que as pessoas continuaram fazendo, e em 2011 alguém simplesmente mandou um e-mail perguntando. A resposta de Thompson foi que nunca foi para o mundo real.

Essa é a palavra dele, que é o que o registro contém, e é o lugar apropriado para deixar a questão. O ponto da palestra nunca foi que aquele compilador específico estivesse por aí. Foi que o ataque é possível, barato e indetectável pelo método que todo mundo usa para estabelecer confiança.

## Por que revisar o fonte não salva você

Esta é a parte a levar a qualquer discussão sobre código aberto e auditoria, e precisa ser dita com precisão, porque é fácil exagerar nas duas direções.

Código aberto significa que o fonte pode ser lido. Não significa que o binário que você está rodando corresponde ao fonte que foi lido. Entre os dois estão um compilador, um ligador, um ambiente de compilação, um sistema operacional e uma cadeia de ferramentas, cada uma delas também compilada por alguma coisa. O ataque de Thompson mora nessa lacuna, e a lacuna existe seja o projeto aberto ou fechado.

Note também que a mesma lacuna derrota a linha de defesa seguinte. O [artigo sobre código perfeito](https://ronutz.com/pt-BR/learn/there-is-no-perfect-code) registra o caso Juniper, em que uma constante alterada num gerador de números aleatórios produzia saída *criptograficamente indistinguível* da original - então testar o comportamento do produto também não teria achado. A revisão de fonte falha contra Thompson; o teste comportamental falha contra a Juniper. O que resta é procedência: você consegue estabelecer que este binário veio daquele fonte?

## O único método que responde formalmente

Por vinte anos a resposta honesta foi que não se conseguia, e a regressão de Thompson parecia infinita: para confiar no compilador é preciso confiar no compilador que o construiu, e assim para trás, para sempre.

David A. Wheeler quebrou isso. Apresentou a **Diverse Double-Compiling** na conferência ACSAC em 2005 e a expandiu numa tese de doutorado na George Mason University em 2009, intitulada *Fully Countering Trusting Trust through Diverse Double-Compiling*. O enquadramento do próprio Wheeler sobre o que está em jogo é direto: as contramedidas conhecidas eram grosseiramente inadequadas, e se o ataque não pudesse ser combatido, atacantes poderiam subverter em silêncio classes inteiras de sistemas e ganhar controle completo sobre sistemas financeiros, de infraestrutura, militares e de negócios no mundo todo.

A sacada é usar o determinismo do compilador contra ele. Compile o fonte do compilador com um **segundo compilador, inteiramente diferente** - que não tem razão para compartilhar a infecção do primeiro. O resultado é um compilador funcionalmente equivalente, mas construído de outro jeito. Agora use *esse* para compilar o fonte do compilador original de novo. Se o compilador original for honesto, o binário produzido bate com aquele de que você partiu. Se ele carregava o truque de Thompson, não bate, porque o segundo compilador, confiável, não tinha instrução de reinserir nada.

Continua sendo, até onde a literatura registra, o primeiro e único método que fecha formalmente a regressão. Wheeler também aponta que Thompson não foi o primeiro a levantar a questão: uma avaliação da Força Aérea sobre o Multics fizera a mesma observação antes.

## O descendente moderno: builds reproduzíveis

A dupla compilação diversa é rigorosa e raramente executada. Sua prima prática hoje é difundida e vale entender como a resposta operacional.

Um **build reproduzível** é aquele em que o mesmo fonte, construído por qualquer um, a qualquer tempo, em qualquer máquina conforme, produz um artefato **idêntico bit a bit**. Essa propriedade soa banal e não é. Se um build é reproduzível, muitas partes independentes podem construir o mesmo fonte e comparar resumos criptográficos, e uma divergência prova que uma delas foi comprometida. Converte a pergunta sem resposta - minha cadeia de ferramentas é honesta? - numa pergunta respondível: builds independentes suficientes concordam?

Chegar lá é engenharia sem glamour: remover carimbos de tempo, ordenar arquivos, eliminar caminhos de compilação e nomes de máquina da saída, fixar a versão de toda dependência. Debian, Arch, Tails, Bitcoin Core e um número crescente de projetos fazem isso. A maior parte do software não faz, e é por isso que a seção seguinte é possível.

## Por que este é o ancestral da taxonomia de cadeia de suprimento

Releia Thompson e toda rota da [taxonomia de cadeia de suprimento](https://ronutz.com/pt-BR/glossary/supply-chain-attack) é uma variação da mesma observação: a coisa que você revisou não é a coisa que rodou.

O **XZ Utils** é o parente moderno mais próximo. A porta dos fundos não estava no repositório git que todos podiam ler - estava no tarball de lançamento, em scripts de compilação, ativada apenas quando o pacote era construído para uma distribuição. Quem auditasse o fonte no próprio site do projeto não acharia nada errado, exatamente como Thompson especificou.

A **3CX** é a outra metade: o fonte estava bem e o *ambiente de compilação* fora comprometido, então a saída era maliciosa e corretamente assinada. A assinatura atestava que o binário viera do pipeline que dizia; o pipeline era justamente a coisa que fora tomada.

E o caso do **ScreenOS da Juniper** é a versão criptográfica, em que nem a saída era distinguível da correta.

## O que um profissional deve de fato fazer

Ninguém vai fazer dupla compilação diversa na própria cadeia de ferramentas, e fingir o contrário desperdiça o tempo de quem lê. As práticas transferíveis são menores e reais.

**Saiba a partir de quê você constrói, e confira se bate com o que o upstream publicou.** A porta do XZ estava no tarball e não no repositório; comparar os dois teria mostrado a diferença. Pouquíssima gente compara.

**Prefira projetos que produzem builds reproduzíveis**, e diga isso nas perguntas de compra. É uma propriedade concreta e verificável, ao contrário da maior parte das alegações de segurança de uma ficha técnica.

**Trate o sistema de build como infraestrutura de produção**, porque é. Ele guarda chaves de assinatura, tem acesso de rede, roda código de dependências, e um comprometimento dele é um comprometimento de tudo que ele já entregou. A maioria das organizações protege os servidores de produção e deixa o servidor de build com a equipe que precisou dele.

**E lembre a que pergunta uma assinatura responde.** Ela diz que um binário saiu de um pipeline específico. Não diz absolutamente nada sobre se o pipeline era honesto - que é a frase que Thompson escreveu em 1984, reenunciada no vocabulário de 2026.

## Fontes

- [Ken Thompson, "Reflections on Trusting Trust", palestra do Prêmio Turing, Communications of the ACM volume 27 número 8, agosto de 1984: o subtítulo pergunta até que ponto se deve confiar na afirmação de que um programa está livre de cavalos de Troia, e sugere que talvez seja mais importante confiar nas pessoas que escreveram o software; a palestra abre com o comentário de receber a honraria tanto por oportunidade e acaso quanto por mérito técnico](https://www.cs.cmu.edu/~rdriley/487/papers/Thompson_1984_ReflectionsonTrustingTrust.pdf)
- [Resumo do artigo pela Carnegie Mellon: Thompson decompõe o ataque em três estágios, sendo o primeiro um programa em C capaz de se reproduzir](https://www.cs.cmu.edu/afs/cs/academic/class/15712-s99/www/summaries/Thompson84.html)
- [Sobre o mecanismo: Thompson criou uma versão do compilador C que, ao receber o fonte do programa login, compilava junto uma porta dos fundos; acrescentou também a capacidade de reconhecer quando estava recompilando a si mesmo, de modo que o novo compilador conteria tanto a porta no login quanto o código para inserir os dois cavalos de Troia num compilador recém-compilado, e o fonte do compilador nunca mostraria que qualquer um deles existia](https://aeb.win.tue.nl/linux/hh/thompson/trust.html)
- [Resumo do Center Consulting: o movimento final é ensinar o compilador a reconhecer quando está compilando a si mesmo e reinserir os dois truques; feito isso, o fonte malicioso pode ser apagado, o defeito segue vivendo no binário do compilador, invisível em toda listagem de fonte, e é passado adiante a cada vez que o compilador compila uma nova versão de si](https://www.centerconsulting.com/code-library/papers/reflections-on-trusting-trust)
- [Micah Kepe, citando uma troca de e-mails de 2011 em que Ezra Lalonde perguntou diretamente a Thompson se o compilador com cavalo de Troia fora de fato construído e distribuído: segundo Thompson, nunca foi para o mundo real; a moral do artigo é que não se pode confiar em código que você não criou inteiramente, "especialmente código de empresas que empregam gente como eu"; Thompson chamou aquilo do programa mais gracinha que já escreveu](https://micahkepe.com/blog/thompson-trojan-horse/)
- [David A. Wheeler, "Fully Countering Trusting Trust through Diverse Double-Compiling": uma avaliação da Força Aérea sobre o Multics e a palestra Turing de Thompson mostraram que compiladores podem ser subvertidos para inserir cavalos de Troia em software crítico, inclusive neles mesmos; se o ataque passa despercebido, nem a análise completa do código-fonte de um sistema acha o código malicioso que está rodando; as contramedidas conhecidas eram grosseiramente inadequadas, e se o ataque não puder ser combatido, atacantes podem subverter em silêncio classes inteiras de sistemas](https://www.researchgate.net/publication/245578769_Fully_Countering_Trusting_Trust_through_Diverse_Double-Compiling)
- [Sobre o trabalho de Wheeler: o artigo da ACSAC de 2005 "Countering Trusting Trust through Diverse Double-Compiling" foi expandido em sua tese de doutorado de 2009 na George Mason University, e continua sendo o primeiro e até agora único método que quebra formalmente a regressão infinita de Thompson, virando o determinismo do próprio compilador contra ele](https://www.sumitchouhan.com/when-the-compiler-lies-lessons-from-reflections-on-trusting-trust-and-the-science-of-verifiable-software)
- [Resumo acadêmico sobre a importância do ataque: a genialidade está na capacidade de autopropagação, já que o compilador comprometido reconhece e reinsere a porta dos fundos em novas versões do compilador mesmo que o código malicioso seja removido do fonte; o trabalho de Thompson evidencia que ferramentas de software podem ser comprometidas de modos que escapam à inspeção tradicional e que a confiança precisa ir além do código-fonte, alcançando toda a cadeia de ferramentas, lançando as bases para entender ataques à cadeia de suprimento de software](https://arxiv.org/pdf/2508.12054)
