Ken Thompson's Turing Award lecture, "Reflections on Trusting Trust", showed that a compiler can be altered to insert a backdoor into programs it builds, and to re-insert itself when it compiles a new compiler. Reading the source code of either program would reveal nothing wrong.
The idea in plain terms
Picture a compiler that notices when it is compiling the login command and quietly adds a secret way in. Now add a second trick: the compiler also notices when it is compiling a copy of itself, and adds both tricks to the new compiler.
Once that compiler binary exists, you can delete the malicious lines from its source. Every new build made with the old binary still carries the behaviour forward. The source looks clean because the problem lives in the binary that builds it.
The Wikipedia article on the topic dates the speech to 1983 in its body, while its reference list cites the Communications of the ACM article as August 1984. The article does not resolve the difference, so if the exact year matters to you, check the original publication. It also says the attack was first described by Karger and Schell in 1974, and that Thompson implemented it.
Why people still talk about it
The lecture makes the point that trust is relative. You trust your code, but also your compiler, your linker, your operating system and the people who built them. People review source, not machine code, so the lower layers get little scrutiny.
Modern build chains make that chain longer, not shorter. Package registries, CI runners and base images are all things you run without reading.
A defence that exists
David A. Wheeler described diverse double-compiling in his 2009 PhD dissertation at George Mason University. The method compares the stage one and stage two compilers built with two different compilers. If they match as expected, a trojan in just one of the original compilers is ruled out.
According to the article, Wheeler used it to check that the GCC 3.0.4 C compiler was free of trojans, with Intel's icc 11.0 as the second compiler.
What to take from it
- Reproducible builds make this kind of tampering detectable, because independent builds should match.
- Using more than one toolchain gives you a cross check.
- Provenance records that say which tool built which artifact turn "trust me" into something you can inspect.
This does not mean you must rebuild the world. It means that when you decide what to trust, you should write the list down, including build tools.
A small thought experiment
Ask yourself which tools in your build you have never inspected. For most teams the list includes the compiler, the package manager, the CI runner image and the base container. Now ask which of them could be swapped without anyone noticing. If the honest answer is that nobody would notice, you have found a place where trust is assumed, not checked. You do not need to fix all of them at once. Pick the one with the most reach, usually the CI image, and make its source and version explicit. Then record a hash of what you use, so a silent change shows up as a difference.
Quick check
Why does deleting the malicious source not fix the problem?
Because the compiler binary already contains the behaviour and re-inserts it whenever it builds a new compiler.
What does diverse double-compiling do?
It compares compilers built with two different compilers to rule out a trojan present in only one of them.
If you want evidence of what went into a build, Safeguard supports SBOM generation and dependency scanning, and you can try a free scan at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.