What the source published
The study's premise is that finding and fixing vulnerabilities one by one scales poorly: fixing even a critical bug tells you nothing about the ones that remain. The alternative is to map which code is reachable, then remove or restrict whatever a given deployment does not need to expose. That does not delete unknown vulnerabilities, but it makes them harder to reach and so less severe — better security without ever having to find an individual bug.
Claude was run over 25 open-source projects in languages including C, C++, Java, PHP and Python, totalling more than five million lines of code. It built an inventory of over 17,000 options, of which 3,842 were related to security-relevant controls or features, and found 493 issues in total. The projects fall into three groups by exposure: public-facing, gated behind authentication, and private to the operator's own environment — 10, 11 and 4 projects respectively.
The surprise was the gated group: all eleven had code that was unintentionally reachable, including 93 unnecessary pre-authentication surfaces in the default setup, 37 places where code executed or state was recorded before authentication, and 61 option combinations that silently weakened a pre-authentication control. None of these would necessarily be exploitable alone, but together they create a much larger attack surface than necessary.
Try it: run the three passes on your own project
- Start with an inventory: have Claude list every external entry point and option in your service, and mark which security control each one relates to, before judging any of them.
- Pass one, default reachability: find code that is reachable in the shipped default setup but is not used by any default functionality, and aim to remove it or move it behind an explicit opt-in.
- Pass two, early reachability: find sensitive, complex code that runs before a hard gate such as authentication, or before any user interaction, and confirm it truly needs to sit there.
- Pass three, interacting options: check options in pairs for combinations that are each reasonable alone but silently disable or degrade a security control when set together.
- Confirm every finding before acting: require a dynamic trace or a minimal reproduction that proves reachability, rather than accepting a conclusion drawn from reading code alone.
- Close the loop: delete what you can, move the rest behind authentication or an opt-in, then rerun the same three passes to confirm the findings are gone.
The full picture: what the best findings looked like
The interacting-options pass produced the most interesting results: 162 security-sensitive combinations that were accepted with no error, no warning and no documented behaviour. In 94 cases the combination silently turned a security control off; the other 68 were inconsistencies inside the same mechanism, such as a listener staying reachable after the settings said it was disabled, or precedence depending on the order of lines in a file. One pattern appeared independently in four unrelated projects: access rules written with hostnames or wildcards were compared as plain text against client IP addresses because reverse DNS lookups were off, so a deny rule could never match and the list failed open.
The case study is OpenSSH. Claude traced the input paths of the SSH daemon in the 10.4 release and found roughly 4,500 lines of new, experimental ML-DSA-44 post-quantum signature code that an unauthenticated client could reach in the default setup — about 16% of its pre-authentication code — even though the algorithm was not enabled and even when an administrator explicitly excluded it: the daemon parsed whatever key type the client sent and verified certificate signatures before checking whether the type was allowed. Anthropic reported it with patches; the 10.5 release moved the check earlier, and Claude then found two gaps in that fix — the check read the algorithm name the client advertised while the parser followed a type string embedded in the key blob, and the certificate path ran full CA signature verification before consulting the settings. The final fix, shipped in 10.6, placed the checks inside the parser itself, before deserialization or signature verification, and removed roughly a fifth of the code an unauthenticated client could previously reach.
How to read this
The lesson for ordinary teams is the order of work: shrink the surface first, then argue about bugs. Bug counts are unknowable, but reachable code can be inventoried and closed off, and one pass at it reduces the severity of every unknown bug at once. The 21-year-old conflict between two options in one project underlines why this suits a model: pairwise checking is tedious, systematic and easy for a careful human to miss.
Anthropic has combined the three methods into one reusable Claude skill and is integrating it into its open-source scanner. Each pass starts fresh with an empty context, carrying only a short note from the previous pass, and every finding must be confirmed with a dynamic trace. If you borrow one thing for your own workflow, borrow those two rules: separate passes with isolated context, and no finding counts without runtime evidence.
Sources: [1]
Key takeaways
- Change the order: inventory and shrink externally reachable code first; the severity of unknown bugs drops across the board.
- The three passes are default reachability, early reachability, and option combinations that weaken controls — 493 issues across 25 projects, with every gated project affected.
- The dangerous failures are silent: 162 accepted option combinations raised no error, and 94 of them quietly switched a security control off.
- Even OpenSSH shipped about 4,500 lines of reachable experimental code; the fix removed roughly a fifth of its unauthenticated surface.
- Adopt the method faithfully: three separate passes, isolated context each time, and a dynamic trace to confirm every finding.
Sources: [1]

