The Confused Deputy
Your most dangerous attacker never gets a key. They find someone who already has one and ask nicely.
A bank teller carries the master key to the vault. You haven't got one and you never will, so you don't even try the vault. You go up to the counter instead and fill in a normal withdrawal slip, and on the line marked transfer to you put the vault's own account number. The teller does this a hundred times a day, so they reach for the key they're paid to carry and open the vault for you. Nobody picked a lock. No rule got broken. The teller did exactly their job, with exactly the authority they were trusted to hold, and they did it for the wrong person.
There's a name for that teller. A computer scientist called Norm Hardy named it back in 1988 - the confused deputy - and it is still the shape of the worst breaches we have.
We tend to picture an attacker as someone in a hood. A cracked password, a forced door, some clever exploit smuggled past the guards. So that's where the money goes, on the perimeter. But there's a whole family of attack that never goes near the perimeter. The attacker holds nothing, has guessed no password, and nothing is broken anywhere. What they do is find a program that already holds power, and they get it to spend that power on their behalf. The malice belongs to them. The authority is borrowed. And it all comes down to a distinction we hardly ever say out loud, which is the difference between what a program is allowed to do and who it is doing it for. Those are two separate things. The trouble lives in the gap.
Hardy's own story is small and it is complete and it is quietly horrifying. There was an old shared mainframe with a compiler on it, and the compiler lived in a privileged corner of the machine where ordinary users couldn't write. It needed somewhere to keep its own statistics file, in that corner, so it had been handed a standing permission to write there. A key to its own room, if you like. Then one day a user ran the compiler and told it where to put its debugging output, which you were perfectly allowed to do. The filename they gave was the system's billing file, and that lived in the privileged corner too. So the compiler took its standing key, opened the file and wrote straight over it, and the billing records were gone. Nothing was malformed. Nothing was exploited in the sense we usually mean. A trusted helper got asked an innocent question and reached for the wrong key to answer it. Hardy's diagnosis was that the compiler was serving two masters at the same time, its own purpose and the user's, and it had no way of telling which one it was acting for at any given moment.
The deputy gets confused because its power is just sitting there. It sticks to the program by default and it's available to anything the program can be talked into, never mind who's asking or why. The compiler didn't decide to use its billing-file key for a stranger. The key was on its belt and the request reached out and used it. That's the whole difference, really, between authority you carry around everywhere - a master key you wear out of habit and grab without thinking - and authority that gets handed to you for one job, a single key for a single door that opens nothing else. Nearly every system is built the first way because the first way is easy. You pin the power to the program and you let it do what it's told. The catch is that doing what it's told is the attack.
Then in 2019 the same teller showed up holding the keys to a hundred million people. Capital One was running a piece of software whose entire job was to go off and fetch web requests for the bank, which makes it a deputy by trade. A former cloud engineer sent it a request, and the request was put together so that the thing it went off to fetch wasn't an outside website at all. It was the cloud's own internal address, a special endpoint that every server can reach, and what that endpoint hands back is the server's own temporary credentials. The software fetched it, exactly the way it was built to, and passed the keys straight back. And the keys belonged to a role far more powerful than a thing that fetches requests has any need to be. It could list and read the bank's stored data. With that borrowed authority she walked off with more than a hundred million credit-card applications. That included the social-security numbers of roughly a hundred and forty thousand people, and the bank-account numbers of tens of thousands more. Nobody broke into the software. It did its job. The intent behind the request was hostile and the authority the software held was enormous, and there had never been a wall built between the two.
It's worth noticing what wouldn't have helped here. When you hear the word breach the instinct is to reach for cleaner input. But there was nothing dirty about this input. The attacker's request was perfectly well-formed, and so was the compiler's filename forty years earlier. A bad input is a lie about the data. A confused deputy is a true and proper request that the program just had no business honouring with the power it happened to be holding at the time. You could have scrubbed the request all you liked and it would have changed nothing, not while the deputy still carried a key that opened the world. Guarding the door does you no good when the guard on the inside will open any door he gets asked about nicely enough.
Which brings us to the cure, the one everybody can recite and almost nobody actually does. Everyone quotes least privilege as a slogan. What it really means is the uncomfortable up-front work of making sure each program holds only the authority its current task needs, and only for as long as it needs it, and better still authority that turns up pinned to the request rather than living on the program permanently. The fetcher should have held a key that reached the outside world and nothing more. The powerful role should have been allowed to read one narrow thing and not the vault. And the deepest version of the idea, which is the one Hardy was pointing at, is to stop keeping the question of what to act on separate from the permission to act on it. You make them a single object instead, so a program can only ever use authority that was deliberately put in its hand for this exact job. The teller can't open the vault for a stranger if the only key in their hand is the one the customer just slid across the counter, and that key opens a single box. The attacker's whole craft is finding power lying around with nobody's name on it. So the defence is to leave none of it lying around.
In the manifesto, this is tenets (XVI) and (IV).
Sources
- [Capital One 2019] Capital One, "Information on the Capital One Cyber Incident". Capital One, 2019. https://www.capitalone.com/digital/facts2019/. The breach figures: around 100 million US applications, roughly 140,000 Social Security numbers and tens of thousands of bank-account numbers; tenets XVI, IV.
- [Dennis & Van Horn 1966] Jack B. Dennis & Earl C. Van Horn, "Programming Semantics for Multiprogrammed Computations". CACM 9(3), 1966. https://dl.acm.org/doi/10.1145/365230.365252. The capability as an unforgeable token of scoped authority, pinning power to the request rather than the program; tenet XVI.
- [Hardy 1988] Norm Hardy, "The Confused Deputy (or why capabilities might have been invented)". ACM SIGOPS Operating Systems Review 22(4), 1988. https://dl.acm.org/doi/10.1145/54289.871709. The compiler tricked into overwriting a protected file because its standing authority could not be told apart from the caller's; tenets XVI, IV.
- [Khan et al. 2022] Shaharyar Khan, Ilya Kabanov, Yunke Hua & Stuart Madnick, "A Systematic Analysis of the Capital One Data Breach: Critical Lessons Learned". ACM Transactions on Privacy and Security 26(1), 2022. https://doi.org/10.1145/3546068. The exploit chain: a misconfigured WAF, an SSRF reaching the EC2 instance metadata service, and an over-privileged IAM role that could list and read the S3 buckets; tenets XVI, IV.
- [Saltzer & Schroeder 1975] Jerome H. Saltzer & Michael D. Schroeder, "The Protection of Information in Computer Systems". Proc. IEEE 63(9), 1975. https://web.mit.edu/Saltzer/www/publications/protection/. Least privilege: each component holds only the authority its task needs, so a confused deputy's reach is bounded by what it was never granted; tenets XVI, IV.
One of a series of field notes on building software for the way minds actually work: tired, distractible, ordinary, and now partly machine. They all lead back to the manifesto behind them, The Shape of the System.