Attack Surface Reduction With Claude: Shrink What Strangers Can Reach Before You Find a Single Bug
Anthropic used Claude to find code that strangers can touch before logging in. Here is the idea in plain terms, and how to run the same three checks on your own stack this week.
Almost every security tool asks the same question: where is the bug?
That question has a cost. You only get protection after somebody finds the specific flaw, writes the specific patch, and you install it. Everything in between is a waiting room, and attackers like waiting rooms.
On October 20, Anthropic's Frontier Red Team published a study that asks a different question: which code can a stranger reach that they should never be able to touch at all? The best example came from OpenSSH, the remote-login server (sshd) that a huge share of Linux machines run. In its default setup, about 4,500 lines of new, experimental cryptography code were reachable by anyone on the internet before they logged in. Anthropic's word for this kind of work is "economically," and that word is the real news.
The result is a security habit you can start today: shrink what can be reached, and every bug you have not found yet gets less dangerous.
What "attack surface" means, in one paragraph
Picture your server as a building. The attack surface is every door, window and mail slot a stranger can use. Most security work checks whether each lock is strong. Attack surface reduction asks a simpler question first: why does this building have a window into the server room at all? If you brick it up, it does not matter whether the lock on it was any good.
In software, the "windows" are features that are on by default, code that runs before anyone proves who they are (pre-authentication code), and settings that silently undo each other. None of these are bugs on their own. They are places where a bug would hurt.
What Anthropic actually did
Claude went through 25 open-source projects, more than five million lines of C, C++, Java, PHP and Python, looking for three kinds of unneeded reach. The post describes them by function rather than by name:
- Default reach. Code that runs in the shipped default configuration even though no default feature needs it.
- Early reach. Complex or security-sensitive code that runs before a gate, such as login, or before the protocol reaches the state where that code makes sense.
- Settings that cancel each other. Two options that are each reasonable alone but, together, silently switch off a security control.
It also sorted projects into three groups. Public projects exist to serve anyone, so a lot of default reach is expected. Gated projects are meant for logged-in users, so very little should run for a stranger. Private projects serve the operator's own environment.
The tally: more than 17,000 configuration options inventoried, 3,842 of them security-relevant, and 493 issues found. Among the findings, 162 security-sensitive setting combinations were accepted with no warning or documentation, and in 94 of those a security control was silently turned off.
Two details from the post are worth stealing.
One pattern showed up independently in four unrelated projects. An access rule names a hostname, say "block anything from badhost.example." But if reverse DNS lookups (turning a connecting IP address back into a hostname) are off, the server only ever sees an IP address. A hostname rule can never match an IP, so the deny rule never fires, and in Anthropic's words "the list would fail open." Nothing crashes. Nothing logs an error. The rule simply does nothing, and it looks fine in the config file.
The other detail: one conflicting pair of certificate options, where a second setting silently dropped a certificate requirement, had sat in its project for 21 years.
The OpenSSH story, and the lesson inside it
Anthropic calls OpenSSH "some of the most heavily audited code in the world." That is why the finding lands.
In the default configuration of OpenSSH 10.4, Claude found roughly 4,500 lines of experimental ML-DSA-44 code (a new post-quantum signature scheme) reachable before authentication. That was about 16% of the pre-authentication code in a default sshd. As the post puts it, "There is no good reason for this complex, memory unsafe code to be reachable."
OpenSSH 10.5 moved the check earlier, before the key was parsed. It still had two gaps, and they are the most useful part of the whole study:
- The check trusted the algorithm name the client advertised, but the parser chose what to parse from a type string inside the key itself. A client could advertise one key type, pass the check, and still send an ML-DSA key that got parsed.
- Signatures on user keys were gated, but the certificate authority signature path was not, and certificate key types were enabled by default.
The full fix, which shipped in 10.6, put the checks inside the parser itself, so the allow-list checks (the list of permitted key types) run before the key's bytes are unpacked into data structures (deserialized). Anthropic says the changes removed "roughly a fifth of the OpenSSH code that an unauthenticated client previously could have reached."
Here is the lesson in plain words: a gate that checks the label instead of the contents is a gate with a side door. You will find this pattern in your own code wherever you validate a Content-Type header and then parse whatever bytes actually arrived.
Why this beats hunting bugs one at a time
Bug hunting is a race you run after the fact. Reach reduction is a bet you place before.
When you remove 4,500 lines from what a stranger can touch, you have not fixed any known vulnerability. You have made every unknown vulnerability in those lines unreachable without a login. Anthropic states the idea directly: "reducing code reachability can reduce the severity of unknown vulnerabilities."
AI changes the math here. Inventorying 17,000 configuration options by hand, then reasoning about which pairs conflict, is the kind of tedious work humans skip. A model does not get bored on option 9,000. Anthropic's claim is that Claude "can meaningfully, and economically, improve software security," and the honest reading is that this job was always worth doing and rarely affordable.
There is a safety detail in how Anthropic ran it, too. For default-configuration findings, modified builds had to pass the project's own test suite plus a black-box regression suite (tests that only poke the program from outside, like a user would) with results identical to the original build, and "any gate that would change a non-default configuration is set aside for a human to decide." The model proposes. The tests and a person decide.
Put this into practice
The post does not link a standalone download of the skill; it says Anthropic is working to integrate it into OSS-Scanner, its opt-in vulnerability service for eligible open-source projects. It also says the broad method should work without the specific skill. So you can run a smaller version with whatever coding agent you already use (Claude Code, Codex, or similar). Pick one service you expose to the internet and budget an afternoon.
Step 1: Get the effective configuration, not just the file. Includes, defaults and overrides all change what the program actually does. Many servers can print the fully resolved version:
sudo sshd -T # OpenSSH: dump the effective server config
sudo nginx -T # nginx: test config and print all of it
php -i # PHP: print every effective setting (CLI build)
One catch: these show what a fresh start would load, not what the already-running process has in memory. If the service was started with extra command-line flags, an alternate config path, or the files changed since the last reload, check those too. For sshd, Match blocks only apply when you pass connection details with -C (the sshd manual covers -T and -C, and the nginx switches page covers nginx's -T). Save the output next to the source code or the docs for the version you run.
Step 2: Run three passes, one prompt each. Keep them separate so the agent stays focused. These are my prompts, modeled on the three categories in the post:
Pass 1 (default reach): Using this effective config and the source,
list features that are ON but that our deployment never uses.
For each: the config line, the code it enables, and whether it runs
before authentication.
Pass 2 (early reach): List code paths that parse untrusted input
before authentication or before the protocol reaches the state where
that input makes sense. Flag any check that trusts a declared type
or name instead of inspecting the actual bytes.
Pass 3 (settings that cancel): List option combinations in this
config where one setting weakens or disables another security
setting. Include rules that can never match (for example, hostname
rules when reverse DNS is off).
Step 3: Change only what you can test. For each finding you act on, turn the feature off or move the check earlier, then run your test suite and a smoke test against the old behavior. If a change alters something a customer might rely on, it goes to a human, the same rule Anthropic used.
What to expect: most findings will be boring. A module nobody uses. A legacy auth method still enabled. A rate limit set in one block and overridden in another. That is the point. Boring findings are cheap to fix, and each one closes a window.
Honest limitations
- This is research, not a product. Anthropic calls the post a preview of initial research and says these techniques give "only a very limited view" of what is possible.
- Unneeded reach is not a breach. For the gated projects, Anthropic says none of the issues "would have been immediately exploitable on their own." You are lowering risk, not closing known holes. Do not let this replace patching.
- The model will be wrong sometimes. It will call a feature unused when some integration depends on it. That is why the test suite and the human sign-off are not optional.
- Your own run is not Anthropic's run. A few prompts in a coding agent are a sketch of the method, not the skill they built, and they will miss things the full three-pass process catches.
- You cannot fully reproduce Anthropic's numbers. The post reports aggregate results; the 25-project list and per-project findings are not on the page.
- Config is only half the picture. Reach also depends on network rules, proxies and who can hit the port. A clean sshd behind an open firewall is still exposed.
Where this leaves you
The question "where is the bug?" will keep mattering. Patches still ship, and you still need to install them.
But you now have a second question that costs less and pays out before anyone finds anything: what can a stranger reach that they never needed? Pick one service. Dump its real config. Run the three passes. Turn off one thing nobody uses. Then do it again next month, because defaults change every release.
Sources: Anthropic, "Using Claude to reduce the attack surface of code" (October 20, 2026); Anthropic, OSS-Scanner announcement; OpenBSD sshd manual; nginx command-line switches.