Skip to main content

Security

AI Finds Vulnerabilities Faster Than Teams Patch: A 2026 Security Checklist for Teams Shipping AI

AI now finds and exploits flaws faster than most teams patch. A checklist from October 2026: same-day patching, SBOMs, fail-closed scans and keys you can rotate.

11 min read
Two lanes on a dark grid: a red attackers bar that starts four days before a blue fix-published line, and a defenders lane where a dashed, striped bar asks when your fix reaches production.

On 17 October, a honeypot run by Amazon received a request that should not have existed yet. It was an attempt to exploit PHP2Shell, a pair of critical remote code execution bugs in PHP, and it arrived four days before the vulnerabilities were publicly disclosed. The bug had been found with an AI model. The fix had not shipped. Someone was already trying it.

Short answer, if that is what you searched for: AI has made finding vulnerabilities cheap for defenders and attackers alike, so the gap between "a flaw is known" and "a flaw is exploited" is now hours, sometimes negative. Teams need a patch path measured in hours, scanners that fail loudly, and secrets they can rotate without a deploy.

The best account of that week is Gergely Orosz's The Pulse: Time to rethink software security because of AI? in The Pragmatic Engineer. Read it. I'm not going to retell it line by line. I want to ask a narrower question: what does that week mean for a company like ours, which ships AI agents and software that AI helped write?

Key takeaways

  • In October 2026 a critical PHP bug was exploited before disclosure, and mass attempts followed within hours of the fix. Your patch process is now part of your attack surface.
  • The secrets attackers wanted were AI provider keys. If you ship AI, your keys are the prize.
  • A vulnerability scanner that cannot reach its database can print "0 known vulnerabilities". Check exit codes, not output.
  • Rotating a key should not require a redeploy. Railway's customers learned this at the worst moment.
  • Most of this is old advice. What changed is how quickly skipping it hurts.

What happened in the week of 17 October 2026?

Here is the short version, with every date taken from the vendors' own disclosures.

A vertical timeline from 30 April 2025 to 26 October 2026: eMudhra's weak CA keys, PingCAP's four-week intrusion, the first PHP2Shell exploit attempt and OpenCode's stolen keys on 17 October, Chrome blocking eMudhra intermediates and Railway spotting an attack on 20 October, PHP fixes and Railway's secrets breach on 21 October, Railway builds returning on 22 October, and CISA listing PHP2Shell on 26 October.

eMudhra. Eight intermediate certificate authority keys at the Indian CA turned out to be guessable. As Gergely documents, using eMudhra's own explanation on Mozilla's Bugzilla, one 384-bit private key was the number 4. The certificates dated from April 2025. Google blocked the eight intermediates in Chrome through a CRLSet update. Browsers were protected quickly. Server-to-server traffic depends on whoever maintains your trust store.

PingCAP. Between 9 September and 7 October, someone used stolen service account credentials to get into PingCAP's internal systems, copy data and obtain source code. PingCAP found out on 7 October. That's four weeks of an attacker inside a database vendor's control plane. Its own remediation list includes "alerts for unusual access and large data exports", which tells you what wasn't there before.

PHP2Shell. Researchers at Calif found a critical flaw using an OpenAI model as part of OpenAI's Patch the Planet effort; Wiz found both bugs independently. PHP shipped fixes for 8.2 to 8.5 on 21 October, rated 9.2 on CVSS v4. Cloudflare had WAF rules on by default from 03:02 UTC, about nine hours ahead of disclosure. Its CEO Matthew Prince posted that attackers were on it before the announcement, and Gergely reports Cloudflare saw millions of attempts within hours of the patch. CISA added both CVEs to its Known Exploited Vulnerabilities catalogue on 26 October.

Railway and OpenCode. On 17 October, OpenCode reported a breach in which customer AI API keys were stolen. On 21 October, Railway disclosed that an attacker may have accessed encrypted environment variables and decrypted some of them. Railway's preliminary report says the campaign was "attempting to obtain AI provider API keys to perform distillation attacks".

And behind all of it, a warning from May. Anthropic's CEO Dario Amodei said that AI had opened a narrow window to fix tens of thousands of vulnerabilities found by Anthropic's Mythos model, because rival models were "maybe six to 12 months" behind. October looked a lot like that window closing.

Why does AI vulnerability discovery change the patching maths?

Finding a memory-safety bug in PHP used to take a rare kind of person and a lot of time. Now a model can do much of the searching. That cuts both ways: the same capability that let Calif find PHP2Shell is available, in some form, to whoever is attacking you.

The second effect is subtler. A patch is a map. The moment PHP published its fix, the diff showed where to look. Gergely makes this point well: attackers can now hand that diff to an agent and point it at every unpatched server on the internet.

So the real question is no longer "how fast do we patch?" in the abstract. It's "how many hours between a fix being published and it running in our production?" Here is what that looked like for PHP2Shell, using only public dates.

A diagram of the PHP2Shell timeline: a red band marked exploited under embargo from 17 October to disclosure on 21 October, Cloudflare WAF rules at 03:02 UTC, PHP fixes and surging attempts on 21 October, and CISA's listing on 26 October; below it, five steps that remain for your team after day 0: learn it affects you, open the upgrade PR, pass tests, deploy, and restart running processes.

Look at step five. Tenable relays Google Cloud's guidance that installing updated PHP packages does not patch processes already running: PHP-FPM and Apache keep the vulnerable code in memory until they restart. I'd bet a fair number of teams "patched" on 21 October and stayed exposed for days. Would yours have caught that?

What does this mean if you ship AI agents?

This is the part most coverage will miss. The Railway attacker was hunting for AI provider API keys. OpenCode lost AI API keys. If your product calls a model, your model keys are now high-value targets in their own right, worth stealing for free inference or to distil someone else's model.

Agents make it worse in three ways.

First, agents hold credentials. An agent that reads your ERP and calls a model has at least two keys, often more, and they tend to sit in the same environment variables Railway customers had to rotate.

Second, AI-built software pulls in dependencies fast. A coding agent asked to "add PDF export" will happily add a library, and nobody reviews the transitive tree it brings. That's the tree PHP2Shell-style bugs live in.

Third, agents act at machine speed. If an attacker gets an agent's token, they don't get a person typing slowly; they get everything that token can do, as fast as the API allows. We wrote about this failure mode in how to secure enterprise AI agents.

The 2026 security checklist for teams shipping AI

A grid of nine cards: patch with a same-day path for critical CVEs, keep an SBOM for every deployable, run scanners in CI that fail closed, rotate secrets without a redeploy, alert on unusual access, least privilege for agents and tokens, point AI at your own code, keep a rehearsed runbook, and shrink vendor blast radius.

To make this concrete, I built two small sample services in a scratch folder with deliberately old dependencies: a Node orders-api (Express 4.17.1, axios 0.21.1, jsonwebtoken 8.5.1, lodash 4.17.20) and a Python app (Flask 2.0.1, requests 2.25.1, PyYAML 5.3.1, Pillow 9.0.0, Jinja2 3.0.1). Everything below that looks like terminal output is what the tools actually printed.

1. Is there a same-day path for critical CVEs?

You need two speeds. Routine updates can wait a few days, which also protects you from a poisoned release. Security fixes should open a pull request the moment an advisory lands.

Renovate supports exactly this split. In its configuration schema, vulnerabilityAlerts defaults to opening PRs immediately with no schedule and no release-age delay, while minimumReleaseAge holds back ordinary updates. A starting renovate.json:

{
  "extends": ["config:recommended"],
  "minimumReleaseAge": "3 days",
  "osvVulnerabilityAlerts": true,
  "vulnerabilityAlerts": { "labels": ["security"] }
}

I checked these option names against the schema shipped in the renovate 42.99.0 package; I haven't run Renovate against a live repository for this article. Dependabot security updates do the same job on GitHub. The tool matters less than the rule behind it: a critical fix gets reviewed and deployed the same day, and someone owns that.

2. Do you have an SBOM for every deployable?

When the next PHP2Shell lands, the first question is "are we affected?" If answering that means asking every team to check, you've lost a day. A software bill of materials makes it a lookup. npm can produce one with no extra tooling:

npm sbom --sbom-format cyclonedx --package-lock-only > orders-api.cdx.json

On the sample, that produced a CycloneDX 1.5 document listing 67 components, and osv-scanner read it back and reported 47 known vulnerabilities in 10 of them. Store one SBOM per build, next to the artefact.

3. Do your scanners run in CI, and do they fail closed?

Here is npm audit on the Node sample:

Terminal output of npm audit on the orders-api sample: high-severity advisories for axios and jsonwebtoken, then a summary of 10 vulnerabilities, 3 low and 7 high.

Note "Will install jsonwebtoken@9.0.3, which is a breaking change". That's why automatic patching is not the same as automatic merging: someone still has to run the tests.

pip-audit on the Python side found 94 known vulnerabilities across all five packages (trimmed):

$ pip-audit -r requirements.txt --disable-pip --no-deps
Found 94 known vulnerabilities in 5 packages
Name     Version ID               Fix Versions
-------- ------- ---------------- ------------
flask    2.0.1   PYSEC-2023-62    2.2.5,2.3.2
requests 2.25.1  PYSEC-2023-74    2.31.0
pyyaml   5.3.1   PYSEC-2021-142   5.4
pillow   9.0.0   PYSEC-2022-168   9.0.1
…
jinja2   3.0.1   PYSEC-2026-1471  3.1.6

For a single tool across ecosystems, Google's osv-scanner reads lockfiles from npm, PyPI and more. I built it from source with go install (version 2.7.0). With its offline database it found 111 vulnerabilities across 15 packages in both samples, and exited with status 1:

Terminal output of osv-scanner with the offline database: 15 packages affected by 111 known vulnerabilities, 8 critical and 56 high, followed by a table of OSV IDs, CVSS scores, packages, versions and fixed versions, and an exit status of 1.

Now the run that taught me something. My sandbox blocks outbound calls to api.osv.dev. Without the offline flag, this is what came back:

Terminal output of osv-scanner when its network calls are blocked: red errors saying requests were forbidden, then a summary line reading 0 packages affected by 0 known vulnerabilities, and an exit status of 127.

"Total 0 packages affected by 0 known vulnerabilities." Same code, same 111 problems. The tool did the right thing with its exit code, 127, and printed errors. But picture a CI script that greps the summary, or pipes output through tee without set -o pipefail. It goes green. A scanner that fails open is worse than none, because it tells you you're safe. Fail the build on any non-zero exit, and alert if the scanner hasn't completed a run in a day.

4. Can you rotate a secret without a redeploy?

Railway's customers were told to rotate everything, while builds were paused. Its status page shows the incident opening at 07:24 UTC on 21 October; builds came back for Enterprise at 04:00 UTC the next day and for every plan by 23:22 UTC. For most of a day, the choice was rotate and go down, or stay up and hope.

The fix is architectural: services read secrets at runtime from a secrets manager with short leases, so rotation is a config change, not a release. We go deeper on this in keeping API keys and secrets away from AI agents. For AI keys specifically, set spend limits and alerts at the provider, so a stolen key shows up as a bill spike within hours rather than at month end.

5. Would you notice an attacker inside for a month?

PingCAP's attacker used valid credentials. Nothing was "broken"; it was just someone else logging in. What catches that is access monitoring: a new identity using a service account, a token used from an unusual network, a large export at 3am.

This one is personal for us. When we tested the governance of Ware, our own simulated-warehouse demo with a real AI recovery agent, we found that its audit log could be edited or deleted without anyone noticing. A log an intruder can rewrite is not monitoring. It's now append-only and hash-chained. If you take one thing from this section, make sure your logs live somewhere the systems they describe cannot write to.

6. Are your agents and tokens on least privilege?

Every agent gets its own identity and the narrowest scope that does its job, with short expiry. Not the admin token from someone's laptop. The pattern we follow, described on our AI governance page, is deny by default with policy in code, and autonomy granted per operation as it's earned. A sibling article covers the mechanics in least-privilege access for AI agents.

7. Are you pointing AI at your own code?

Gergely's conclusion is that defenders will have to use more AI, and I agree. If a model can find a bug in PHP, it can find the one in your invoice parser. Run a model-assisted review on every PR that touches authentication, parsing or anything that takes outside input. Treat its findings like a junior reviewer's: useful, not final.

8. Is your incident runbook written and rehearsed?

When a vendor emails "rotate everything", who does it, in what order, and how do you know you're done? Write down every secret, where it's used and how to rotate it, plus who can approve a production deploy at 2am. Rehearse it once a quarter.

9. Does one vendor's breach become yours?

Railway, OpenCode and PingCAP were all vendors to someone. Assume one of yours will be breached. Keep the blast radius small: separate keys per environment and per service, no production credentials in a platform's environment variables if a runtime fetch will do, and egress rules so a stolen key is less useful from outside your network.

What we don't know yet

Plenty. Nobody has said how the PHP2Shell details leaked before disclosure; Amazon says it "remains unclear". Railway's and PingCAP's reports are preliminary. And I can't tell you whether October was a spike or the new normal. Gergely's update lists more critical CVEs in the days after, which isn't encouraging.

If you want a second pair of eyes on where your own pipeline stands, that's what our AI readiness audit is for.

Frequently asked questions

What is PHP2Shell?

PHP2Shell is the name for CVE-2026-109618 and CVE-2026-109619, two critical PHP flaws that allow unauthenticated remote code execution. PHP published fixes for 8.2 to 8.5 on 21 October 2026. Exploit attempts began four days earlier, and CISA listed both as known exploited on 26 October.

Is AI finding vulnerabilities faster than teams can patch them?

In October 2026, yes. PHP2Shell was found with an AI model and exploited before disclosure, with mass attempts within hours of the fix. Most teams cannot test and deploy a dependency upgrade in hours without a pipeline built for it.

How do I patch faster without breaking production?

Split updates into two lanes: routine updates wait a few days, security fixes open a PR immediately. Keep good automated tests so a breaking upgrade fails in CI, and remember to restart running processes after upgrading runtimes like PHP.

Which free tools scan dependencies for known vulnerabilities?

npm audit for Node, pip-audit for Python, and Google's osv-scanner for many ecosystems at once. Run them in CI and fail the build on a non-zero exit code, because a scanner that cannot reach its database may still print zero vulnerabilities.

Why were AI API keys targeted in the Railway breach?

Railway's preliminary report says the attacker was trying to obtain AI provider API keys to perform distillation attacks. Model keys give free inference and access to model outputs, so any team shipping AI should treat them as high-value secrets with spend alerts and fast rotation.

One email when we publish something worth your time

No cadence, no drip sequence. We write when we have learned something running agents in production, which is not weekly.