Security for startups

The Decade-Old Bug Is Now a One-Week Find

AI vulnerability discovery is turning years-old bugs in PHP and Linux into week-long finds. What old code you expose, who owns it, and a checklist.

In this post
  1. Four bugs in one month
  2. Why old code is the target
  3. Disclosures are up a lot more than exploitation
  4. What this means for a small company
  5. The checklist

This month a PHP bug that had been in the code for more than a decade turned into a critical, unauthenticated remote code execution flaw. The researchers at Wiz say a single person did the work in a week, work that would previously have taken a world-class team months. Around the same time a Linux kernel bug from 2017 and a GitLab bug from 2014 surfaced. AI tools found the PHP and kernel bugs; nobody has said that about GitLab. They raise a question most small companies can’t answer: what old code do we expose to the internet, who owns it, and when did anyone last read it?

I’m not going to repeat the triage steps for PHP. I wrote those up in what to do if your servers run PHP. I’m also not going to argue that fix capacity, not discovery, is the constraint for small teams. I covered that in the remediation bottleneck post. This post is about the code that sits there for years because nobody has had a reason to read it.

Four bugs in one month

php2shell. Wiz’s write-up says “the vulnerable code had been there for more than a decade” and that it affects releases back to PHP 5.4. The two CVEs, CVE-2026-109618 and CVE-2026-109619, were fixed on October 21 in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Wiz found the bug on August 19 and reported it to PHP on August 24. Their own description of the process: “We used Wiz Atlas, Gemini 4 Argon and GPT-5.6 Sol throughout this research.” And: “a single researcher completed in a week what previously would have taken a world-class team months of work.” Cloudflare says the vulnerability was leaked before the official release date, and watchTowr reports exploitation in the wild.

Vghost. CVE-2026-74580 is a flaw in the Linux vhost code that gives local root and, in some configurations, a guest-to-host escape. The Hacker News reports that “the flaw sat in the code for about nine years,” introduced in Linux 4.11 in 2017. Tencent Zhuque Lab found it with Corvus AI, which they describe as a multi-agent system for kernel vulnerability research. The write-up came out October 12, with the fix in commit de845981da67.

PwnEscape. CVE-2026-99999 is a Linux kernel networking bug that lets a guest VM read host memory. Paulos Yibelo of pwn.ai found it during Vercel’s sandbox challenge with a harness that used GPT-5.6 Sol as the main reasoning engine and humans directing it. According to The Hacker News, it took “three days” and under $700 in API tokens. It was the only Critical finding among the 1,285 reports Vercel paid out on. The coverage I found doesn’t say how old the bug is, so I won’t guess.

GitLab. CVE-2026-110264 is a CVSS 10 unauthenticated remote code execution, fixed October 21. It comes from an integer overflow in regex compilation and affects every self-managed GitLab version back to 7.0, which dates to 2014. It’s the fourth code execution flaw in GitLab’s regex engine that the same researcher, joaxcar, has reported in a month. Nothing I’ve read says AI found this one, and I’m not claiming it did. I’m including it because it’s the same shape in the same week: a twelve-year-old bug in code that a lot of companies run themselves.

There’s one more, from April: Copy Fail, CVE-2026-31431, a Linux bug from the 4.14 era in 2017 that Theori found with AI scanning help. So this has been going on since at least April.

Why old code is the target

For a long time, most old code was safe because reading it was expensive. A kernel subsystem, an HTTP parser or a regex compiler that has worked for ten years gets little attention. The bug is in there, but finding it takes someone who understands the code, has weeks to spend, and has a reason to pick that corner out of millions of lines.

The Wiz quote above is about that cost. The most concrete number I have comes from PwnEscape, a bug with no reported age: three days and under $700 in tokens, with humans steering. Those are different bugs found by different people with different tools, so I wouldn’t average them into a rate. What both say is that reading kernel and runtime code closely is cheap enough now that someone will do it on purpose.

“Someone” includes attackers. An attacker can point the same models at the same old code a defender can.

Disclosures are up a lot more than exploitation

Bishop Fox’s analysis from September 30 says the CVE Project published 57,871 records in the first eight months of 2026. Disclosures are up roughly 85% over last year. Known exploited vulnerabilities rose about 14% over the same period. They say “a meaningful share of the increase is AI-assisted research,” and they also observed AI-assisted research “producing a high volume of CVEs with minimal real-world impact.”

So the raw count overstates the danger. More CVEs does not mean 85% more breaches. A lot of what’s being filed is low-impact, and if you chase every CVE number you’ll burn your week on things that don’t matter.

None of the four bugs above is low-impact. php2shell is unauthenticated remote code execution with exploitation reported in the wild. GitLab is a 10.0. PwnEscape and, in some setups, Vghost reach from a guest to its host, which matters a great deal if you run anything multi-tenant.

I expect patch volume to get worse before it gets better, though I don’t have a number for that. There’s a lot of old code nobody has read, and reading it keeps getting cheaper.

What this means for a small company

If you’re a startup with a few engineers, you probably don’t run a kernel and you don’t write your own regex engine. You run a pile of other people’s code, and a lot of it is old. Some of it is in your product, like a PHP admin panel or the WordPress site marketing set up in 2021. Some of it is under the product: the OS image and the container base layer. And some of it nobody remembers, like a staging box left up after a demo.

The exposure question has three parts.

What is exposed? Start with everything that answers on a public IP or a public DNS name, including what sits behind a load balancer. CISA warns that “PHP is often a component of other software and prevalence may not be directly observable,” so you may not see it from the outside. Build the list from your cloud accounts, DNS records and package manifests.

Who owns it? Every exposed service needs a name next to it. When a CVSS 10 lands for a thing nobody owns, the first hours go to finding out who can restart it. In a company of twenty, ownership often belongs to someone who left, or to a contractor, or to “whoever set it up.”

When did anyone last read it? For code you wrote, when did someone last review it? For code you run, when did you last look at what version it is, what branch it’s on, and whether that branch still gets fixes? A self-hosted GitLab on a version two majors behind is a different risk from one on the current release, because the fix for the next bug may not exist for your branch.

Writing down what’s running doesn’t need a security hire. If that’s where you are, what a fractional security engagement actually looks like covers what the first weeks involve, and the vCISO math for AI founders covers when it pays to hire for it.

The checklist

Run this against anything that faces the internet. A spreadsheet is fine. Write down the answers, because the point is that on a bad day you aren’t reconstructing them from memory.

  1. Inventory exposed services. Pull your public DNS records, your cloud load balancers and security group rules, and a port scan of the IP ranges you own. Compare what you find to what you thought you had. Expect at least one surprise.
  2. Record age and upstream. For each one, write the software, the version, the release date of that version, and where it comes from: a distro package, a vendor, a container image, your own repo.
  3. Name an owner. One person, not a team. If you can’t name one, the service goes on the list for item 7.
  4. Check the branch. Is that version on a branch that still gets security fixes, from upstream or from a vendor you pay? For PHP this month that decided who could patch at all, and I went through the options for end-of-life branches in the php2shell post. GitLab’s October 21 release went further back than usual: The Hacker News notes that four of the fixed versions are older than GitLab normally patches.
  5. Time a patch and restart. Can the owner patch and restart it in under a day, without needing to ask permission or find a maintenance window that doesn’t exist? Do it once on a non-critical service to find out.
  6. Check how it’s built. If it’s baked into an image, can you rebuild and redeploy the image? If it’s a vendor appliance, who at the vendor do you call?
  7. Remove what you can. Old demos, abandoned staging environments, admin panels nobody has opened this year, test vhosts.
  8. Put the rest behind auth. Anything that doesn’t need to be public goes behind a VPN, an identity-aware proxy or at least an IP allowlist. An unauthenticated remote code execution bug is much less useful when the attacker can’t reach the port.
  9. Set a read date. For the services you keep, put a date on the calendar for the next time someone looks at the version, the branch and the config. Quarterly is a reasonable start.

You won’t finish this in a day, and the first pass will be ugly. Start with items 1 through 3 on the most exposed ten services and see what comes up.

If you want help building that inventory, or a second opinion on what you find, that’s the kind of work I do through consulting.