Death of Security by Obscurity
The economics of security flipped. Most teams haven't noticed yet.
I should feel very scared right now. Everyone should be freaking scared. But I think we have had so many emotional events happening in the world recently that people have stopped feeling much of anything, and that is the most dangerous part of where we are. The line we used to tell ourselves — “we are not a bank, we are not NASA, we don’t need that level of security” — is no longer an option. We just haven’t felt it yet.
Try this thought experiment. Imagine your company’s source code is made public tomorrow. All of it. How would you feel? I bet most of you would be freaking scared. Not because of IP. Because of the quality. Because of the spaghetti conditions in some files. Because of the strange customer-specific branch nobody touched in three years. Because of the comment that says “// TODO: fix this before prod” still sitting in prod. Because of the auth path that “almost” works. Because of the secret that probably should have been rotated.
For years, a lot of teams treated security as something between a badge, a process, and a hope. Of course everyone said the right thing. “We treat security as a first-class citizen,” and so on. But in practice, unless you were in a regulated industry, security was often optional in the only sense that matters — optional in priority. You followed best practices. You ran dependency scanners. Maybe you had a penetration test every six months because customers asked for it. Maybe you had a badge in your sales deck. But you weren’t really thinking about security as part of how the product works.
Banks, Automotive, Aerospace was different. In those industries, security is existential — if a bank loses trust, the bank is dead, and if an automotive system fails the wrong way, people die. So they built heavy processes around it: requirements, reviews, evidence, traceability, release gates. All the painful stuff. For a long time it was easy for the rest of us to look at that and say: yes, but we are not a bank.
I used to think this way too. At Tyk, I work with banks, governments, and large enterprises, and I was often annoyed by how slow some of their security processes were. Every release needed another check. Every patch had to go through another team. Every dependency update could become a discussion. Sometimes it took weeks or months. From the outside it looked like bureaucracy, and a lot of it was bureaucracy. But I changed my mind on the core idea. Those industries understood something the rest of us could safely ignore for a while: security is not something you add at the end. It is part of what the system is.
Security is a market
This is the part most engineers do not internalise. There is a real economy of people who make money by finding vulnerabilities in software. Some sell to bug bounty programmes. Some sell to brokers. Some sell to whoever is buying. And some just use what they find directly — exfiltrate data, sell the data, blackmail companies, take systems hostage.
That market used to be expensive to enter. Finding bugs took time. Understanding a custom system took time. Building an exploit took time. So attackers focused where the return was high — WordPress, Drupal, popular CMS plugins, well-known SaaS — anything they could exploit a million times after building it once. If you were niche, you were maybe scanned, but rarely understood. That asymmetry was your moat. Nobody admitted it out loud, but it was the moat.
A few years ago at Tyk we had a slightly crazy idea: let’s find open-source Tyk users across the world and see if some of them could become paid users. The idea wasn’t crazy. The crazy part was how easy the technical side was. I wrote a scanner that could scan the public IPv4 internet in a matter of hours. The whole internet. Once you do something like that yourself, “nobody will find us” stops sounding like a serious argument.
You can reproduce a small version of this at home. Run a basic HTTP application on a fresh public IP, expose a port, and watch the logs. Within minutes you start seeing requests: WordPress paths, admin URLs, old plugin routes, random probes, exploit attempts for software you are not even running. Most of it is dumb traffic. That is exactly the point. The internet does not need to know who you are before it starts touching your system.
So scanning was already cheap. The thing that just changed is understanding.
What AI actually changed
AI did not invent insecure software. We were already very good at writing insecure software. What AI changed is the cost of finding the insecurity, and the cost of understanding an unfamiliar system. A model can read a codebase and ask the questions a tired team will never ask, because everyone is busy shipping the next thing. It can build a personalised exploit for an unfamiliar service in hours, sometimes minutes. It can chain three small bugs that nobody would have chained manually because the manual cost was too high.
The reason this is genuinely scary is the floor, not the ceiling. The economics have flipped to the point where a kid in a basement with a decent model can build a personalised exploit for your specific codebase, scan the whole public internet in an afternoon, find every instance of your software, and run that exploit against all of them. Nothing about that sentence requires a state actor.
And this is not theoretical. Anthropic’s Project Glasswing reports that Anthropic and around 50 partners used Claude Mythos Preview to find more than ten thousand high- or critical-severity vulnerabilities across important software in the first month, with the bottleneck shifting from finding vulnerabilities to verifying and patching them.  Cloudflare pointed the same model at more than fifty of their own repositories and found that real vulnerability research needs a harness — architecture context, narrow tasks, validation — but with that harness, it works.  Anthropic also says Mythos-class capabilities will soon exist in many AI labs.  Open source historically catches up in around six months. The gap closes; it does not stay open.
So the relevant question is not whether this exact model is public today. The question is whether your security model assumes this capability stays rare. I would not bet a company on that.
Assume your source code is already out
Here is the uncomfortable truth: you should stop wondering whether your source code is going to leak. You should assume it already has.
I know how that sounds. But look at what just happened to GitHub. On May 20, 2026, GitHub said it had detected and contained a compromise of an employee device involving a poisoned third-party VS Code extension. GitHub’s assessment was that GitHub-internal repositories were exfiltrated, with the attacker’s claim of around 3,800 repositories being directionally consistent with the investigation. GitHub said it had no evidence of impact to customer repositories outside its own internal ones, but it still had to rotate critical secrets and continue analysing logs. 
Think about who this happened to. This is GitHub. Owned by Microsoft. With MDM, EDR, hardened endpoints, mature processes, more security engineering than almost any company on earth. One developer. One poisoned VS Code extension. Source code gone.
And the exposure window was tiny. The Nx Console advisory says the malicious version was live in the Visual Studio Marketplace for about 18 minutes and in OpenVSX for about 36 minutes. Eighteen minutes was enough.
Now compare that to your company. If this happened to GitHub, with everything GitHub has, do you really believe nobody has done the equivalent to your team? Be honest. How many extensions did your team install last week? Do you know what any of them do? When did each one last update? Who reviewed it?
So assume it. Assume some snapshot of your source code is already out there. It does not even need to be the latest one — an older snapshot is enough to know where to look. And once an attacker has that, they can use AI to do exactly what defenders are starting to do: read everything, model the system, and build the exploit shaped specifically for you.
That changes the threat model fundamentally. Black-box testing — sending requests, observing responses, fuzzing endpoints, inferring behaviour — is already dangerous. White-box is a different category. With your code in hand, the attacker does not need to guess. They can follow your authentication logic. They can inspect your authorisation paths. They can see your tenant isolation, find the one resolver that does not validate ownership, see the timeout path nobody tested, find the internal endpoint that was “safe” because nobody knew it existed, find the retry that is not idempotent, read the comment that says “this should never happen,” and find the strange customer-specific branch that everyone forgot about.
If your answer to that scenario is “well, they probably do not know how the system works,” then the source code itself was part of your security boundary. And that boundary is gone.
CI/CD is not plumbing anymore
The other place this hits hard is the build system. We used to think of CI/CD as plumbing. From an attacker’s point of view, CI/CD is one of the most interesting machines in the company — it usually has source code, deployment credentials, package publishing tokens, cloud access, GitHub tokens, and secrets for half of the internal systems.
The Trivy incident in March 2026 is the most uncomfortable example because Trivy is a security tool. A trusted security scanner became the attack vector — version tags in aquasecurity/trivy-action were force-pushed to credential-stealing malware, and the action stole everything CI runners had access to.  CanisterWorm followed a similar pattern: attackers stole npm tokens from compromised pipelines and used them to publish backdoored versions across every namespace they could reach. The malicious packages ran on postinstall — install was enough. 
So zero trust now has to include code. But notice the ladder. First, don’t trust your dependencies — pin versions, quarantine updates. Then, don’t trust the actions running in your pipelines — pin those to commit SHAs, not tags. Then ask the harder question: what if the platform itself is compromised, the way GitHub just was? At that point pinning helps but is no longer a complete answer. Each step up the ladder gives the attacker less leverage, but no step makes the problem zero.
This sounds exhausting. It is. But the alternative is worse.
The CVE model is dead
The CVE model still matters, but it cannot be the centre of your security process anymore. For a lot of teams the hidden workflow is still: wait for the CVE, check the severity, patch by priority, hope customers update before something bad happens. That workflow was already fragile. The new world breaks it.
VulnCheck found that in the first half of 2025, 32.1% of known exploited vulnerabilities had exploitation evidence on or before the day the CVE was issued. For a large share of exploited vulnerabilities, the CVE was not the start of danger. It was already late. 
The system producing CVEs is also overloaded. NIST said CVE submissions increased 263% between 2020 and 2025. NIST enriched nearly 42,000 CVEs in 2025, more than any prior year, and still said it was not enough to keep up. In April 2026, NIST moved to a risk-based enrichment model where some CVEs are listed but not immediately enriched. 
And none of that machinery will know the weird things inside your own system. A CVE will not know that your GraphQL resolver crashes a customer’s system on one malformed input. It will not know that your retry path is unsafe when the downstream service writes but your load balancer times out first. It will not know that your PII is in the same database as everything else, and one forgotten SQL injection path could expose more than anyone expected. You need a model of your own system, not just a feed of public bugs.
The intuitive response is “patch faster.” That is not enough either. No matter how fast you patch, if your architecture and development flow do not enforce security boundaries by default — if they do not force you to think about security as you write the code — patching will not save you. Every new release becomes a new attack surface, and a personalised exploit can be ready in five minutes. I am not exaggerating.
Cloudflare made the more important point. They described teams talking about a two-hour SLA from CVE release to patch in production, but if regression testing takes a day, getting to two hours means skipping something. Their conclusion is architectural: make exploitation harder even when a bug exists, put defences in front of the application, design the system so one flaw does not give access to everything else, and make fixes deployable everywhere at once. 
That is the difference between reactive security and designed security. Reactive security tries to outrun the attacker. Designed security assumes bugs exist and limits what one bug can do.
So how do you live in this world?
The first thing is to actually accept where you are. You have to go through the stages — angry, scared, in denial, eventually acceptance. Most teams stop at denial. They tell themselves the old story: we are not big enough, we are not interesting enough, who would target us. That story is over.
Once you accept it, the next move is not “make everything secure.” That is too vague and usually becomes theatre. Start with the worst case. What can kill your company? How would I leak all customer data? How would I bypass authentication? How would I bypass tenant isolation? How would I poison a release? How would I get production credentials out of CI? How would I make one customer’s system go down with a single malformed request? How would I turn a slow downstream service into a cascading outage?
This is uncomfortable, but it gives you priorities. The worst case is not the same for every company. For a bank, anything touching the money is existential. If a bank loses money, the bank is dead. For a SaaS company automating LinkedIn outreach, leaking a list of customer emails is bad but survivable. The same company being used to impersonate its users and send messages on their behalf is not survivable. That is the death of the company.
If everything is critical, nothing is critical. But some things really are: authentication, authorisation, tenant isolation, secrets, CI/CD, package publishing, admin APIs, customer data, billing data, and anything that turns one bug into many customers affected. Be honest about which of these are existential for you, and put real process around those.
By real process I do not mean bureaucracy for its own sake. I mean what banks and government suppliers actually do, and I am saying this from experience — I spent years building software that went through that kind of pen-testing, the long kind, with people who do this for a living. Pin everything that runs in your build. Make secrets short-lived. Quarantine dependency updates before they reach your main branch. Treat anything that executes code in your dev or build environment as part of the product, because it is.
And then there is the boring part, the part that works much better than people want to admit: checklists.
Checklists are not exciting. They are one of the main reasons software engineering has ever shipped anything reliable. They are why planes fly. They are why a CT scanner does not lie to a radiologist. The reason they work is not because they are clever. They work because they force you to think about things you would otherwise skip.
If you have a login system, you should be forced to think about password reset, previous password reuse, account enumeration, timing attacks, brute force, lockout, and what happens when the email provider is down. If you make an outbound HTTP call, you should be forced to think about timeouts, DNS hangs, retries, idempotency, downstream slowness, partial success, and what happens if the service receives your request but your load balancer times out before you get the response. If your Go code starts a goroutine, you should be forced to think about cancellation, ownership, leaks, blocked channels, and behaviour under load.
None of this is advanced security research. It is basic engineering. But it only happens when the process forces it to happen. The hardest bugs to find are not the ones you wrote wrong; they are the ones you never wrote at all, because you never thought about that case.
And if you decide not to handle something, fine — say it. Log it as a known issue. Put an expiration on it. Hidden gaps are the dangerous ones.
Putting security on autopilot
After years of pen-testing work with banks and governments, I noticed the same kinds of gaps kept coming back. Login systems that didn’t think about timing attacks. HTTP calls that didn’t handle partial success. Goroutines that leaked under load. Not exotic bugs — basic ones, in different codebases, over and over.
So I started writing them down. Open-source projects I had investigated, real incidents I had seen up close, every checklist I had built across years of audits — all of it into a catalogue. That catalogue is what Proof runs on.
Then I built automation around it, because checklists in someone’s head do not scale. This is also why I care about MC/DC. Line coverage tells you a line ran. Modified Condition/Decision Coverage — required by the FAA for Level A software, where failure could be catastrophic — asks whether every logical part of a decision independently affected the outcome.  The bug is rarely “this function was never tested.” It is “this function was tested, but not when auth is false, tenant is different, feature flag is enabled, downstream state is stale, and the retry path is active.” Not the happy path. The combination nobody specified.
Proof works in both directions. From spec to code: if your requirement says “user can log in,” Proof attaches sub-requirements for password reset, timing attacks, enumeration, lockout, dependency failures — and the CI check literally fails if a required item has no test attached. If you decide not to handle one of them, fine — mark it as a known issue, attach an expiry, and it stays visible instead of disappearing. From code to spec: static patterns scan for signals (HTTP client, goroutine, database call, queue), and when one is found, Proof asks the spec whether you have described what happens when the service is slow, down, or partially successful. If the spec is missing, the code is shouting at the spec.
Over time the spec stops being a static document and becomes a living source of truth — in my case, a graph of small interconnected requirements that I treat as more authoritative than the code itself, because the code can drift and the spec is the contract. Spec links to code, code to tests, tests back to spec. If one of them changes, the link becomes suspect, and you have to look again.
This does not replace human security work. It just makes the questions impossible to skip.
Security is everyone’s problem now
Not every company needs to copy bank-level process. That would kill a lot of teams. But every software company needs to copy the posture. Security is not something you bolt on at the end. Your moat is no longer the software you build, or the market expertise, or being first. Your moat is being something people can trust to depend on for a long time.
So assume the internet will find you. Assume your dependencies are not safe by default. Assume one developer tool can become the entry point. Assume your source code has already leaked. Assume attackers can use AI to understand your system faster than you can.
Then ask what still protects you. Do you know which parts of the system can kill the company? Can you rotate secrets quickly? Do you have tests for the behaviours that matter, not just the lines that execute? Do you know when code, tests, and specs drift apart?
Security by obscurity is what dies when attention gets cheap. That world is going away. The practical question now is simple. When someone looks closely at your system — with automation, with your source code in front of them, with AI, and with patience — what will they find?
And what will be your answer?
If any of this is hitting close to home and you want to see what putting security on autopilot looks like in practice, get in touch. I'd love to hear what your team is dealing with — and show you how Proof works on real code. reqproof.com

