# The week of 14-23 October 2026: php2shell, a poisoned LiteLLM, a CVSS 10 in GitLab, and eMudhra's weak CA keys

> Satyajit Ghana — Head of Engineering @ Inkers Technology
> canonical: https://ai.thesatyajit.com/articles/security-week-oct-2026
> date: 2026-10-23
> tags: security, disclosure, infrastructure

This is a defender's write-up of the past week: the eMudhra keys, the PHP RCEs, and whatever else carried a CVSS 10 or was being exploited. For each item: the class, affected and fixed versions, severity as published, exploitation status, who is exposed, and how to check. Nothing here says how to exploit anything. Where a public exploit exists I say so and stop.

I worked from primary records: CVE records from the CVE Services API (`cveawg.mitre.org`), CISA's KEV JSON feed (catalog `2026.10.21`), FIRST's EPSS API (22 October), vendor advisories, and the Mozilla bug where eMudhra is being worked. Every number is labelled **measured** (I read it from one of those files), **reported** (a vendor or researcher says so, and I could not re-check it), or **reasoned** (my own arithmetic on the other two). All times are UTC.

**Updated 23 October.** A widely shared post by fiveoutofnine listed a dozen incidents from the same days, and my first version missed several. The big misses were the LiteLLM supply-chain compromise, which made my "the AI stack was quiet" line wrong, GitLab's CVSS 10.0, and breaches at Railway, TiDB Cloud and Zeabur. I checked each claim against a primary source. What holds is added below. What I could not source is under "Reported only", not in the text.

**Updated again, 23 October.** Another post counted 30 CVEs "reported in a SINGLE day" across PHP, Node.js, NGINX, Go and GitLab. This article had 6 of them. [Every CVE of 21 October](#every-cve-of-21-october) now lists all 30 with severity as published, versions, exploitation and KEV status. None is exploited or in KEV, so the ranking is unchanged.

**Updated 24 October.** Aikido renamed the Brotli bug "HTTP2Shell" as other stacks were found to carry it. [The new subsection](#24-october-http2shell--the-same-brotli-bug-beyond-node) lists each ecosystem's affected and fixed versions from its own advisory, with how to check. Exploitation status is unchanged, so the ranking holds, with one new row on the board.

## The board, and why it is not sorted by CVSS

CVSS describes a bug's worst case in isolation. It does not say whether anyone is exploiting it or whether your copy is reachable. An unexploited 9.8 behind a VPN is a smaller problem this week than an 8.6 on an internet-facing gateway that CISA has watched being exploited. So the board ranks by three published facts:

- **Exploitation.** In CISA's KEV catalog scores 3. So does a malicious release that actually shipped, and a breach the operator itself has confirmed. A vendor's report of exploitation attempts, or keys that have been publicly recovered, scores 2. Nothing reported scores 0.
- **Access needed.** None scores 2. An authenticated user scores 1. An administrator or local access scores 0.
- **Reach.** An internet-facing appliance or web runtime scores 2. A bug that needs a specific configuration or data path scores 1. A local-only bug scores 0.

The total runs from 0 to 7. CVSS is shown, not added. Switch to "CVSS only" and watch GitLab's 10.0 jump to the top and LiteLLM, which has no score at all, fall to the bottom.

<WeekBoard />

The weights are a judgment call, shown rather than hidden. A malicious release counts as no access needed and full reach: whoever installed it already ran the attacker's code. Ties break on how direct the exploitation evidence is, then on CVSS. So LiteLLM 1.107.0 comes first, then the five unauthenticated, internet-facing KEV items. Then Plex, PHP and the three platform breaches at 6. eMudhra's public but browser-blocked keys come next. GitLab's 10.0 sits mid-table: maximal severity, no reported exploitation.

## eMudhra: eight CA keys anyone could recompute

### What happened

eMudhra is an Indian certificate authority whose emSign roots are trusted by the Chrome, Mozilla, Apple and Microsoft root programs. On 17 October at 18:05 a researcher who goes by Wayne emailed all four and eMudhra. He reported that the private keys of eight eMudhra intermediate CA certificates were recoverable, with signed proof that he held all eight ([Mozilla Bugzilla 2083449](https://bugzilla.mozilla.org/show_bug.cgi?id=2083449), reported).

The class of bug is simple to state. A P-384 private key is meant to be a random integer between 1 and a 384-bit group order. Mozilla's Dennis Jackson recovered the keys himself at 21:48 without the reporter's method, then wrote in the bug:

> The 8 impacted keys all used integers less than 256. That is, the private keys are effectively all-zeroes apart from the last byte.

The key space is about $2^{384}$; these keys came from 256 values. The curve and the signatures are fine. The keys were generated badly. Mozilla noted local AI agents recovered them on the first try. Several people recovered them independently, some publicly, which is why Mozilla escalated on 20 October (reported, comment 18). Scott Helme's [write-up](https://scotthelme.co.uk/eight-bits-of-trust-emudhras-ca-keys-cracked-in-milliseconds/) lists all eight values. One TLS intermediate's key was 4, and the two code-signing keys were 66 and 237, as the post said (reported, consistent with Mozilla's "less than 256"). Everything is revoked and blocklisted, so the numbers no longer open anything.

Which certificates: six TLS intermediates, `EM DV/OV/EV TLS CA - G3B` and `- G3C`, under `emSign Root TLS CA - G3`, and two code-signing intermediates trusted only by Microsoft. Sectigo had cross-signed the six under a root Apple and Microsoft still trust, and revoked the cross-signs on 19 October (comment 13). All eight came from a 30 April 2025 ceremony that made 24 intermediates; only the P-384 keys of the B and C series were weak (comment 5).

### Who did what, and when

| Time (UTC) | Event | Source |
|---|---|---|
| 17 Oct 18:05 | Report sent to the root programs and eMudhra | Bugzilla, comment 2 |
| 17 Oct 19:45 | Chrome ships a CRLSet blocking the affected intermediate keys | [Google](https://blog.google/security/protecting-chrome-and-android-users-from-compromised-emudhra-intermediate-ca-certificates/) |
| 17 Oct 22:59 | Firefox OneCRL block complete | [Mozilla](https://blog.mozilla.org/security/2026/10/20/protecting-firefox-users-following-the-compromise-of-emudhra-intermediate-certificates/) |
| 18 Oct 09:24-09:38 | eMudhra revokes all eight (`cACompromise`) | Bugzilla, comment 10 |
| 19 Oct ~22:00 | Android equivalent via Google Play services | Google |
| 20 Oct | Firefox 158.0.1, ESR 115.43.1 and 153.5.1; NSS 3.131.1 drops the root | Mozilla |
| 20 Oct | Mozilla and Chrome announce emergency removal of `emSign ECC Root CA - G3`; eMudhra stops issuing from it | Bugzilla, comments 18-21 |
| 22 Oct | eMudhra announces it will leave the global TLS certificate business | [eMudhra press release](https://emudhra.com/en/press-release/emudhra-to-exit-global-ssl-tls-certificate-business) |
| 27 Oct (PDT, planned) | Root removed from the Chrome Root Store on all devices | Google |

Apple's block on 19 October and Microsoft's on 20 October appear only in news reports. I could not find either vendor's own notice, so treat those two dates as reported second-hand.

### What is and is not affected

Google says no certificate chaining to the affected intermediates was in Certificate Transparency before the block, so no forgery could have worked against a CT-enforcing client (reported). eMudhra says seven of the eight were never in production and the eighth issued nothing ([status page](https://emudhra.com/en/post/certificate-security-incident), reported). That is not "no harm". A forgery needs no log entry to fool a client that skips CT and revocation checks, which is a lot of non-browser software. Cloudflare shipped fixed WARP, Cloudflare One and `cloudflared` (2026.10.2) builds for exactly that reason ([write-up](https://blog.cloudflare.com/emudhra-certificate-compromise/)).

The root removal is what breaks legitimate sites. eMudhra estimated "about 30,000 certs that require migration", 97% via ACME (comment 19). Any chain ending at `emSign ECC Root CA - G3` fails in Chrome once the 27 October removal lands. Google's instruction: "immediately acquire and install a new TLS certificate from another PKI hierarchy".

For India, MeitY said the issue is limited to eMudhra's global website-certificate business and does not touch the DSC and eSign services the Controller of Certifying Authorities regulates (reported, [Business Today](https://www.businesstoday.in/technology/story/impact-has-been-very-limited-meity-on-emudhra-security-incident-says-indian-dsc-and-esign-unaffected-562927-2026-10-21)). eMudhra agrees. I found no statement from the CCA itself. As far as I can tell, Indian DSCs chain to the CCA's own root, not to eMudhra's browser roots. If so, nobody filing returns with a USB-token DSC has anything to change (reasoned, not confirmed by the CCA).

### How to check

- **Browsers.** Nothing to do if they update normally. Restart Firefox for Android if it is older than 158.0.2. That release fixes profiles that were not applying the blocklist at startup (reported, comment 29).
- **Servers and services.** Update the OS CA bundle and any vendored ones, such as Python's `certifi`, Rust's `webpki-roots`, Java `cacerts` and container base images. Mozilla linked the `certifi` and `webpki-roots` updates in the bug. Node.js carries its own CA list. Its 21 October security release lists a `ca-cert` update for "eMudhra Intermediate CA Compromise" on 22, 24 and 26 (measured, from the release page). So the Node update below also fixes this.
- **Your own sites.** Check whether any certificate you serve chains to `emSign ECC Root CA - G3`. If one does, replace it before 27 October.
- **What not to do.** Cloudflare's line bears repeating: "It's important to not resolve these errors by disabling verification."

How keys made under an HSM key-generation policy ended up this weak is an open question on the bug. eMudhra's account, a faulty wrap and unwrap step in the ceremony script, is preliminary and unverified.

## PHP: php2shell, CVE-2026-109618 and CVE-2026-109619

### The leak, and the 10.0 that wasn't

Details leaked before the patch. watchTowr says information circulated on 20 October, ahead of the coordinated date, and that it confirmed the bugs were real (reported). PHP's notice that day reserved "the right to release earlier should details of either vulnerability become public". On 20 October a social post said PHP core had an RCE rated CVSS 10.0, with details due that day. PHP's own pre-announcement that day said "two critical vulnerabilities, both rated CVSS v4.0 9.2" and set the release for 21 October at 14:00 (reported, [php.net](https://www.php.net/)). The published CVE records agree with PHP. Both carry `CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N`, score 9.2 (measured). The "high complexity" and "attack requirements present" in that vector are what keep it under 10. **The CVSS 10.0 figure came from the leak, not from the advisory.**

### What they are

Both are memory-safety bugs in how PHP keeps state across the request lifecycle. Neither needs application code. In the CNA's words, from [GHSA-w8hw-w9fx-j79w](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w) and [GHSA-6wmf-4rv5-p3rp](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp):

- **CVE-2026-109618, "RCE via OOM corruption".** An out-of-memory error can abort a request while internal request memory is only partly initialised. Request cleanup then treats that memory as valid.
- **CVE-2026-109619, "RCE via stale global state".** Request-owned global state can keep pointing at memory that has been freed. A later request on the same worker can use it before it is reset.

Both records list CWE-416 (use after free), CWE-755, CWE-824, CWE-1325 and CWE-1419 (measured). Both credit Wiz, Ryan at Calif.io and OpenAI as reporters. The fixes are credited to four PHP core developers. Wiz says it reported to PHP on 24 August (reported).

### Affected and fixed

| Branch | Fixed in | Status |
|---|---|---|
| 8.5 | 8.5.12 | supported |
| 8.4 | 8.4.27 | supported |
| 8.3 | 8.3.36 | supported |
| 8.2 | 8.2.35 | supported until 31 December 2026 |
| 8.1, 8.0, 7.4 | no release | minimal source backports from PHP; check your distro or LTS vendor |
| 7.3 and older | none | affected per watchTowr; upgrade |

The CVE records list only 8.2 through 8.5, each as "affected below the fixed version" (measured). PHP's news post adds the 7.4, 8.0 and 8.1 backports. watchTowr says older branches back to PHP 5 are affected too (reported). PHP 8.6.0 RC4 carries the fixes; earlier 8.6 builds do not.

PHP says every installation serving web requests is at risk, including PHP-FPM, Apache `mod_php`, `php-cgi`, FrankenPHP and LiteSpeed. It names `mod_php` the highest risk, "with a demonstrated exploit where an unauthenticated request can trigger the attack before any application code runs" (reported). The CLI is out of scope, since the bugs concern persistent workers serving many requests.

### Exploitation status

The sources disagree, so here they are separately:

- **CISA** had "not observed exploitation" on 21 October; its SSVC entry in both records says `Exploitation: none` (measured).
- **watchTowr** says its honeypots saw exploitation attempts against both CVEs from 21 October (reported). It does not say whether any succeeded.
- **A public exploit exists.** The "php2shell exploit" repository names both CVE ids; I am not linking it. Rapid7 found each public exploit worked only on a specific OS, PHP version and web server, and none looked broadly reliable (reported).
- **EPSS** on 22 October: 0.0576 for CVE-2026-109619 and 0.0531 for CVE-2026-109618, around the 93rd percentile (measured).
- **National CERTs** split too. The Dutch NCSC was reportedly investigating "first signs of successful misuse" on 22 October and HKCERT called both exploited; Bitdefender saw no attempts (all reported, via coverage).

So attempts are reported, not verified, and neither CVE was in KEV when I re-read the feed on 23 October (measured, catalog `2026.10.21`).

### The response: offline before patched

What made this week unusual was governments telling people to unplug before the fix existed:

- **CISA** (confirmed, [alert](https://www.cisa.gov/news-events/alerts/2026/10/21/critical-vulnerabilities-php-require-immediate-patching)): if you cannot update, or run 8.1 or older, take PHP-based systems offline until patched.
- **UK NCSC** (confirmed, [guidance](https://www.ncsc.gov.uk/news/critical-security-issue-affecting-php)): if you cannot update or mitigate, "you should consider taking the system offline until it can be fully mitigated", and look for backdoors before upgrading.
- **CERT-EU** (Security Advisory 2026-018), the **FBI** and the **NSA** gave similar advice on 21 October (reported, via coverage; I did not read their originals).
- **Japan.** Prime Minister Takaichi posted on X on the evening of 21 October: prepare to patch, and if you cannot patch quickly, consider suspending your site (reported, [Jiji via nippon.com](https://www.nippon.com/en/news/yjj2026102101249/)). Coverage puts it at 21:55 JST, which is 12:55 UTC and 05:55 US Pacific. That is almost certainly the post's "5:55 in the morning" (reasoned).

Then the sites went dark:

- **Netherlands.** The NCSC took its own site offline, along with other central-government sites ([rijksoverheid.nl](https://www.rijksoverheid.nl/actueel/nieuws/2026/10/21/aantal-websites-rijksoverheid-preventief-offline-na-kwetsbaarheden-php), confirmed). So did the Tweede Kamer ([NL Times](https://nltimes.nl/2026/10/21/dutch-parliament-website-taken-offline-cybersecurity-warning-triggers-precautions)). AFP adds the Port of Rotterdam, Overheid.nl, the KNVB and several hospitals (reported).
- **Elsewhere in Europe** (reported, AFP via [Korea Times](https://www.koreatimes.co.kr/world/20261023/govts-companies-take-websites-offline-over-php-vulnerabilities)): Finland's Valtori, French prefecture sites, Germany's ITZBund, Belgian foreign-ministry sites and the Czech government site. Finland and Germany reported no exploitation.
- **Wikimedia** took some systems down while addressing the PHP vulnerabilities; MediaWiki is PHP. The **Internet Archive** went into emergency maintenance, PHP unnamed. **Something Awful's** maintenance page cites the flaw. In Japan, the Ministry of Finance, the Meteorological Agency and the National Tax Agency suspended services, and pixiv, DMM, niconico and BASE went into maintenance (all reported).

Nearly all were precautions, and most came back within a day. A day of downtime against unpatchable code on servers anyone could reach.

**Which applications.** The bugs sit below application code, so everything on a vulnerable PHP inherits them: WordPress, Drupal, Joomla, MediaWiki, Magento, Laravel (reasoned). Wiz demonstrated unauthenticated RCE against WordPress, Drupal and Joomla (reported). No source I found names Magento or Laravel; that changes nothing.

**How many servers.** I could not find the post's Censys figure of "about 1.5 million servers". CybelAngel counts 2.24 million internet-facing PHP hosts, 59% on branches with no fix coming, and calls it provisional (reported). Order of magnitude only.

### Mitigation, if you cannot update today

PHP is blunt about this: "There are no complete mitigations, updating is the only safe choice." Its stopgaps narrow specific paths. In PHP's own terms:

- **For CVE-2026-109618.** Set `memory_limit=-1` in a way applications cannot override, such as `php_admin_value` in the pool or the Apache config. Keep `post_max_size` low: 8M if you take no uploads, 32M if you do. Enforce request-size, field-count, multipart-part and nesting limits at the proxy. Use a container or cgroup memory limit, not `RLIMIT_AS` or `RLIMIT_DATA`, which PHP warns can cause the very allocation failure involved.
- **For CVE-2026-109619.** Set `session.upload_progress.enabled=0` in `php.ini` or the pool config and restart every worker. Setting it from `ini_set()` or `.user.ini` does not help. On 8.5, also set `fatal_error_backtraces=0`. Fix any fatal errors and timeouts an attacker can reach. Hiding them with `display_errors` or `@` does not count.

CISA's line for unsupported versions is harsher: take PHP 8.1-and-older systems that cannot be updated offline. Restart is the step people forget. A patched package on disk does nothing for an FPM pool that has been running since Tuesday.

### How to check

Check the version that is actually running (`php -v`, or `phpinfo()` behind authentication) against the table. For a distro package, look for the two CVE ids in its changelog. A backport keeps the old version number, which is why the checker below says "check your vendor" rather than "vulnerable" for a distro build. For detection, the indicators PHP worker processes produce are generic. CISA suggests watching for PHP workers that start shells or download tools. Wiz suggests watching for unusual multipart requests followed by memory-limit errors or repeated HTTP 500s, unusually large or malformed `PHPSESSID` cookies, and unexplained worker churn (reported).

<VersionCheck />

The checker is pure version comparison against the advisories' ranges for PHP, Node.js, GitLab, NGINX, Go and LiteLLM. For Node.js and GitLab it counts how many of the release's CVEs still apply to your version. Nothing leaves the browser.

## LiteLLM 1.107.0: a poisoned release, the second this year

This should top a Python shop's list. LiteLLM puts many model providers behind one API, so its proxy usually holds every provider key an organisation has. The maintainers' [incident report](https://docs.litellm.ai/blog/security-incident-oct-21-2026) is the source below unless marked.

- **What shipped.** `litellm==1.107.0` on PyPI, seven wheels, 11:39 to about 13:23 on 21 October. Docker Hub's `v1.107.0`, `latest`, `main-latest` and `main-stable` tags, 11:46 to 14:20. The same tags on GHCR for `litellm`, `litellm-database` and `litellm-non_root`, until about 13:51. The GitHub source tag is clean (reported).
- **What it does.** A credential stealer plus a loader that keeps fetching remote code. The maintainers say Python startup re-runs the planted files, so nothing had to import `litellm`: installing it and running any Python in that environment was enough (reported). Analysts describe it collecting SSH keys, cloud and CI credentials, and the provider keys in a LiteLLM proxy database ([StepSecurity](https://www.stepsecurity.io/blog/litellm-1-107-0-compromised-pypi-backdoored-wheels-credential-stealer), [Socket](https://socket.dev/blog/litellm-compromise), reported).
- **How it got out.** Per the maintainers, an attacker with stolen developer credentials overrode branch protections, pointed a release workflow at a lookalike repository, `Berri-AI/litellm`, and satisfied the approval gate with another account's credentials. They believe the credentials came from GitHub CLI OAuth tokens exposed in an internal deployment's logs, and say that is not yet confirmed (reported). No CVE has been assigned.
- **Second time this year.** In March, `litellm` 1.82.7 and 1.82.8 on PyPI carried credential-harvesting malware ([GHSA-5mg7-485q-xm76](https://osv.dev/vulnerability/GHSA-5mg7-485q-xm76), confirmed). The post's "second time this year" holds.
- **Who is exposed.** Anyone who installed 1.107.0 from PyPI, or pulled one of those image tags, in those windows. Unpinned installs and anything that tracks `latest` are the likely victims. The maintainers say enterprise customers on the private registry were not affected.

**Indicators the maintainers publish:** `cook.pth`, `cook.py` and `sitecustomize.py` in `site-packages`, matching `__pycache__/cook*.pyc` and `sitecustomize*.pyc` files, a `litellm-1.107.0.dist-info` directory, the lock file `/tmp/remote_code_loader.lock`, and the image digest `sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e`. They warn that not finding these files does not prove a host is clean.

**What to do,** in the maintainers' order:

1. Do not run `pip install` first in an affected environment, because Python startup re-runs the planted files. Remove them, and stop the detached Python process holding the lock file.
2. Rebuild environments and images from scratch, pinned to `litellm==1.106.2` or another release from before the incident.
3. If 1.107.0 ran on a host with outbound internet access, assume its data left.
4. Rotate every secret that host could reach: the instance or task IAM role, every provider key in the proxy database, the master and virtual keys, the `DATABASE_URL` password, and anything else in the process environment.
5. On AWS, look in CloudTrail for `GetCallerIdentity` from the instance role around install time, and for that role's credentials being used from outside your infrastructure.

Pin by version and by digest. A tag called `latest` is a promise someone else keeps.

## Three hosting platforms, three breaches

Three platforms disclosed breaches within a week. Railway ties its incident to a series of attacks on platform companies aimed at AI inference providers. That is Railway's framing; I do not link the three beyond it.

- **Railway** (confirmed, [disclosure](https://blog.railway.com/p/security-disclosure-wednesday-october-21st), 21 October). Railway detected anomalous activity in the systems that store customer environment variables. An unauthorized party may have accessed encrypted values and, for some, the decrypted contents. Initial analysis suggests a subset of users, but Railway tells every user to rotate all environment variables, API keys and private registry credentials, and to review service logs. All deployments were paused during the investigation. Railway says it asked upstream providers to revoke keys proactively. Status: `status.railway.com`.
- **TiDB Cloud** (confirmed, PingCAP's [incident report](https://www.pingcap.com/trust-hub/security/security-update-october-2026/), 19 October). Someone used stolen service-account credentials to reach internal systems from 9 September to 7 October, copied data and obtained source code. PingCAP says the exported records include account names and emails, SQL editor text, billing and contract data, and a table of *encrypted* TiDB Cloud API-key values. It found "no evidence that data stored in TiDB was impacted". It invalidated all identified credentials by 14 October. That is "about a month" of access, as the post says. The **10.6 TB** figure is an extortion group's claim. PingCAP neither confirms nor mentions it, so it is unverified.
- **Zeabur** (confirmed, [Zeabur's post](https://zeabur.com/blogs/zeabur-is-shutting-down), 17 October). An attacker reached internal systems and some customer services on 14 October. Zeabur says the incident was broader than its late-August one. So "second breach in two months" holds. The company is shutting down: shared clusters pause on 1 December 2026 and everything stops by 31 December. BleepingComputer reports more than 3.2 million environment-variable records and 321,810 accounts affected (reported; Zeabur's post does not give counts).

On any of these, the response is the same: rotate every credential that lived in the platform, at the provider that issued it.

## GitLab: a CVSS 10.0 in every self-managed release since 7.0

- **What it is.** [CVE-2026-110264](https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/), an integer overflow when compiling a specially crafted regular expression. Under certain conditions it could let an unauthenticated user run code on the GitLab server (confirmed, CVE record). CWE: integer overflow.
- **Severity.** `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H`, **10.0** (measured). EPSS on 22 October: 0.00505 (measured).
- **Affected and fixed.** GitLab CE/EE from 7.0, fixed in 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 and 18.11.13, released 21 October (measured). GitLab 7.0 shipped in 2014, so the post's "since 2014, every self-hosted GitLab for twelve years" is right (reasoned). GitLab.com and GitLab Dedicated are already patched.
- **Eleven more in the same release.** The 19.5.1 release fixed twelve CVEs. The backports to 18.11 through 19.2 carry only this one; the other eleven need 19.3.6 or later. See [Every CVE of 21 October](#every-cve-of-21-october).
- **Not the same as last week's.** GitLab fixed a different CVSS 10.0 regex bug, CVE-2026-97229, on 12 October, in 19.2 to 19.4 only. A server patched then, say to 19.4.2, is still affected by this one (measured, from both records).
- **Exploitation.** None reported by GitLab. Not in KEV (measured). The reporter is credited through HackerOne.
- **Fix and check.** GitLab lists no workaround, so upgrade. Single-node instances take downtime for migrations. GitLab publishes two detections for self-managed instances: crashes of the native regex worker, and bursts of render errors (reported). Check the version on the Admin area's dashboard or `/help`.

## WordPress "XSS2Shell": CVE-2026-64638 is August's bug with a new exploit

A post on 22 October announced "XSS2Shell", a pre-auth XSS-to-RCE chain in WordPress, with a public PoC repository I am not linking. The advisory side:

- **Component.** WordPress **core**, not a plugin: a pre-auth reflected XSS on the login screen (confirmed, [CVE record](https://www.cve.org/CVERecord?id=CVE-2026-64638)).
- **Severity.** `CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:A/VI:H/...`, **8.9** (measured). Reaching code execution needs a victim to visit an attacker's site and interact: the record says "successful social engineering of and explicit interaction by the target victim".
- **Fixed** in [WordPress 7.0.3](https://wordpress.org/news/2026/08/wordpress-7-0-3-release/), released 6 August 2026, and backported to every branch back to 4.7 (confirmed). Credited to pwn.ai.
- **Exploitation.** CISA's SSVC says none. EPSS 0.0089 on 22 October (measured). Not in KEV.

So this is not new: a two-month-old fix got a public exploit. Sites with background updates were patched in August; check that yours took it.

## Node.js: Node2Shell, CVE-2026-111497, and two TLS bypasses

- **What it is.** An out-of-bounds write (CWE-787) in the Brotli decoder of Google's Brotli 1.0.3 through 1.2.0, which Node.js bundles. So it is a core runtime bug, not an application pattern. The Node.js [October 2026 security release](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases) rates it high and credits OpenAI Codex Security.
- **Severity.** Google, as CNA, scores it `CVSS:4.0/AV:N/AC:L/AT:P/PR:N/...`, 9.2 (measured). No EPSS score yet on 22 October.
- **Fixed** in 22.23.4, 24.22.1 and 26.12.1 (21 October). End-of-life lines, 20 and older plus 23 and 25, get nothing. Standalone Brotli: 1.0.10, 1.1.1, 1.2.1.
- **Who is exposed.** Code that decodes untrusted Brotli. Imperva's [write-up](https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/) found two paths: built-in `fetch()` reading a Brotli response, and Express 5 body parsers decoding Brotli bodies. A bare `http` server does not decode on its own (reported).
- **Exploitation.** Imperva reports unreliable code execution on the official 24.22.0 Linux arm64 build; a public PoC exists. Nothing in the wild, not in KEV, SSVC `none` (measured).
- **TLS bypasses, same release** (measured, from the release page). Two **high**: a certificate hostname bypass "when the IP is written fullwidth digits" (CVE-2026-105483), and one "when the host loosely resolves to an IP address" (CVE-2026-106069). One medium, CVE-2026-106072, lets DNS SANs vouch for IP endpoints. All three are mismatches between what the client thinks it reached and what the certificate covers. The release fixed ten CVEs in all; the other seven are in [Every CVE of 21 October](#every-cve-of-21-october).
- **Fix and check.** Update the runtime everywhere, including Node binaries inside container images, which package inventories miss. WAF rules from Imperva and Vercel cover inbound requests only, not a Brotli response you fetch. The same release carries the eMudhra CA update.

### 24 October: HTTP2Shell — the same Brotli bug, beyond Node

On 23 October Aikido [renamed](https://x.com/AikidoSecurity/status/2113759110625906950) the bug "HTTP2Shell", saying it leaves "many libraries and applications using HTTP vulnerable to pre-auth RCE via Brotli decompression", and that fixes were "not yet available for all affected services". It is the same CVE and the same flaw. Nothing new was found on 23 October. What changed is that people noticed the Node.js advisory described a library bug: the CVE record has always named Google's Brotli 1.0.3 through 1.2.0, "on all platforms", and Node was only the first consumer to ship a fix. On 23 October the record's affected list still named only `google/brotli`. Its update added three references: the PyPI advisory, an oss-security post making the same point, and Debian's fix (measured). Aikido's [write-up](https://www.aikido.dev/blog/python-packages-vulnerable-node2shell-brotli-cve-2026-111497) relays OpenAI's account that the root cause was fixed in Brotli's source in February without being recognised as a security bug, and that no release carried the fix until 21 October (reported).

Brotli is only reached where something *decodes* it, and decoding is opt-in in most stacks. That is the exposure question for every row below.

| Ecosystem | Affected | Fixed | Primary source | Decodes untrusted Brotli when |
|---|---|---|---|---|
| libbrotli (C, `google/brotli`) | 1.0.3–1.0.9, 1.1.0, 1.2.0 | 1.0.10, 1.1.1, 1.2.1, tagged 21 October | CVE record (Google as CNA); upstream tags (measured) | Whatever links it calls the decoder |
| Python `Brotli` (PyPI) | 1.0.3 to 1.2.0 | 1.2.1, on PyPI 22 October 13:57 | GHSA-9v8h-qqgm-4m35; PyPI (measured) | It is installed and a library uses it (next row) |
| Python `brotlicffi` | through 1.2.0.2 | 1.2.1.0, on PyPI 22 October 16:19 | GHSA-9v8h-qqgm-4m35; PyPI (measured) | As above |
| urllib3 (so `requests`), httpx, aiohttp | No advisory of their own; they load whichever of the two packages is installed | Update the Brotli package | Their source (measured) | urllib3 and aiohttp clients then advertise `br`. httpx decodes a `br` response. aiohttp's parser, which its server shares, decodes `br` too |
| Node.js | 22, 24, 26 below the fix | 22.23.4, 24.22.1, 26.12.1 | Node.js release (above) | `fetch()` and body parsers (above) |
| Bun | before 1.4.4 | 1.4.4, 22 October | Bun's release notes list "Brotli" among the security fixes and name no CVE; the mapping is Aikido's (reported) | Not stated |
| Envoy | builds pinning Brotli 1.2.0 (1.1.0 on 1.36) | 1.40.0, 1.39.3, 1.38.6, 1.37.8; 1.36.12 on an unsupported branch | Envoy advisory GHSA-3wvj-j6qm-62mr (not readable from here); the pinned Brotli at each tag (measured) | A Brotli decompressor filter is configured |
| Istio | 1.29, 1.30, 1.31 below the fix | 1.29.9, 1.30.6, 1.31.2, 15 October | Istio release notes (measured) | "Users who enable Brotli decompression, for example with an EnvoyFilter" |
| Debian | bookworm 1.0.9-2, trixie 1.1.0-2; sid unfixed | 1.0.9-2+deb12u1 (DLA-4855-1), 1.1.0-2+deb13u1 (DSA-6582-1) | Debian security tracker (measured) | Debian's `nodejs` uses this system library |
| Ubuntu | every release "Needs evaluation", priority Medium | none yet | Ubuntu CVE page (measured) | n/a |

Envoy fixed it early, quietly. Its 6 October releases moved the pinned Brotli from 1.2.0 to an unreleased upstream commit of 30 September, two weeks before the CVE existed (measured, from `bazel/repository_locations.bzl` at each tag). Aikido's line that advisory databases "don't map the CVE to either PyPI package" was out of date by the time I read it: GHSA-9v8h-qqgm-4m35 names `Brotli` and `brotlicffi` with their fixed versions, and OSV carries it as PYSEC-2026-4322 and -4323 (measured, 24 October). Aikido also reports that Apache's `mod_brotli` and NGINX do not decode Brotli by default (reported). The oss-security post calls an OpenSSL path through compressed certificates "conceivable", which is a guess, not a finding.

**Does it move up the board?** No. The CVE record's CISA entry, updated on 23 October, says `Exploitation: none`, `Automatable: no`. It is not in KEV (catalog `2026.10.23`), and EPSS is 0.0048 (measured). The only public code-execution claim is still Imperva's unreliable result on one Node build. "Pre-auth RCE across HTTP" describes the class at its worst, not anything observed. I added one row to the board for the library outside Node. It scores 3: no exploitation, no authentication needed, and reach conditional on a decoder being switched on. Node's row did not move. If a vendor reports attempts, or it lands in KEV, the row climbs to 5 or 6.

**How to check.** Python: `python -m pip show brotli brotlicffi` in every image and virtualenv, including the ones you never chose it for. It arrives as an extra of `urllib3[brotli]`, `httpx[brotli]` and `aiohttp[speedups]`. System library: `dpkg -l 'libbrotli*'` or `rpm -q brotli`, then trust the distro's fixed version, not the upstream number, because a backport keeps the old one. `curl -V` prints the `brotli/x.y.z` it links. Anything that vendors or statically links Brotli needs its own rebuild: Node, Bun, Envoy, compiled Go with `cbrotli`, and your own binaries. The checker above now takes Python and C library versions. Where a product has no fix yet, Aikido's advice is to turn Brotli decoding off until it does (reported).

## Every CVE of 21 October

On 22 October a post counted the CVEs "reported in a SINGLE day": PHP 2, Node.js 10, NGINX 5, Go 1 and GitLab 12, plus eMudhra's CA compromise. Satyajit asked whether this article had all of them. It had 6 of the 30: both PHP bugs, three of Node's and GitLab's critical one (reasoned). This section adds the other 24, each from the vendor's advisory and the CVE record, with the same rule as everywhere else here: class, versions, exposure, fix and how to check, and no exploit detail.

**The counts hold; the "single day" mostly does.** I count 2, 10, 5, 1 and 12, so 30 CVEs (measured). PHP, Node.js and GitLab published on 21 October. NGINX did not: its five fixes shipped on 14 October in 1.31.7 and 1.30.6, the CVE records went public that day, and the 21 October release, 1.31.8, carries no security fix (measured, from nginx.org's changelog and the records). Go released 1.27.3 and 1.26.10 on 19 October by its release history, and the CVE record went public on 21 October at 00:52 (measured).

**None of the 24 changes the ranking.** None of the 30 is in KEV (catalog `2026.10.21`, re-read on 23 October). No vendor reports exploitation, and every record that carries CISA's SSVC entry says `Exploitation: none` (measured). Outside PHP, the highest EPSS on 22 October was 0.00554, for NGINX's CVE-2026-93479 (measured). On the board above, NGINX and Go come in at 3 out of 7: unauthenticated, but each needs a specific configuration or code path. That puts them below GitLab's 10.0, which scores 4.

<DayCves />

The filter is the useful part: "No login needed" narrows the 30 to 17, and "Published severity" puts GitLab's 10.0 first, then the five rows rated critical at 9.2: PHP's two and NGINX's three (measured, from the table's own rows). Node.js publishes a word, not a vector, so its rows sort by that word.

### Node.js: ten CVEs, one release

Every row is fixed in 22.23.4, 24.22.1 and 26.12.1, released 21 October; end-of-life lines get nothing ([release](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases)). Severity is Node's own word. Only the Brotli bug has a public CVE record, from Google as CNA; on 23 October the CVE API returned "does not exist" for the other nine, so they have no vector yet (measured). None is in KEV, and Node reports no exploitation.

| CVE | Component and class | Node.js severity | Lines affected |
|---|---|---|---|
| CVE-2026-111497 | Bundled Brotli decoder, out-of-bounds write (CNA: `CVSS:4.0/AV:N/AC:L/AT:P/PR:N/...`, 9.2) | high | 22, 24, 26 |
| CVE-2026-105482 | `dns.resolve` truncates names that contain a NUL character | high | 22, 24, 26 |
| CVE-2026-105483 | TLS hostname bypass for IPs written in fullwidth digits | high | 24, 26 |
| CVE-2026-106069 | TLS hostname bypass when the host loosely resolves to an IP | high | 22, 24, 26 |
| CVE-2026-105481 | HTTP keep-alive socket processes a response written before the request was sent | medium | 22, 24, 26 |
| CVE-2026-106072 | DNS SANs accepted for non-canonical IPv4 endpoints | medium | 22, 24, 26 |
| CVE-2026-106074 | `crypto.randomUUID()` and `randomInt()` entropy caches saved into startup snapshots and SEAs | medium | 22, 24, 26 |
| CVE-2026-106070 | `ZipFile` returns attacker-controlled prefix bytes after a failed header check | low | 26 |
| CVE-2026-106071 | Permission Model filesystem over-grant via wildcard lookup | low | 26 |
| CVE-2026-106073 | Permission Model bypass with `fs.realpathSync` | low | 22, 24, 26 |

That is 10 CVEs on 26.x, 8 on 24.x and 7 on 22.x (measured, from the release page's per-issue lines). Four are rated high; the Brotli bug and the two TLS bypasses are covered above. The fourth high, `dns.resolve`, matters where a host name an attacker controls reaches a DNS lookup, as with webhook targets or user-supplied URLs (reasoned). The three TLS items together weaken what a Node TLS client checks about the host it reached. So they matter to any process that makes outbound TLS connections to targets someone else can influence (reasoned). Two only bite in specific setups. The entropy cache affects apps shipped as startup snapshots or single executable applications (SEAs): every process starts with the same cached values, so UUIDs repeat. The Permission Model bugs matter only if you run with `--permission` and rely on it as a boundary. How to check: `node -v` in every image, then the checker above.

### NGINX: five CVEs, released 14 October

Fixed in NGINX Open Source 1.31.7 (mainline) and 1.30.6 (stable). F5's records list NGINX Plus fixes in 37.0.5.1 and 37.1.0.1, and in 37.0.7.1 and 37.2.0.1 for the HTTP/3 bug. R33 to R36 are listed as affected with no fix on those releases (measured, F5's CVE records and [nginx.org's advisories](https://nginx.org/en/security_advisories.html)). F5's own K-articles (`K000162416`, `K000162607`, `K000162613`, `K000162606`, `K000162608`) would not render without JavaScript, so the Plus details come from the records F5 published as CNA.

| CVE | Needs this configuration | Class | CVSS (F5, CNA) | nginx.org | Vulnerable (Open Source) |
|---|---|---|---|---|---|
| CVE-2026-15176 | `alias` with `rewrite`, and `$request_filename` in `set`, `return` or a log format | Heap buffer overflow in a worker | `CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/...` 9.2; v3.1 8.1 | medium | 0.1.29 to 1.31.6 |
| CVE-2026-93479 | `map` with regex captures used before the map's output, in `root` or a log format | Heap buffer overflow in a worker | same as above, 9.2; v3.1 8.1 | medium | 1.31.2 to 1.31.6, 1.30.0 to 1.30.5 |
| CVE-2026-97205 | `aio` on, serving SSI pages with `include virtual` | Use after free in a worker | same as above, 9.2; v3.1 8.1 | medium | 0.8.11 to 1.31.6 |
| CVE-2026-97629 | `ssl_session_cache shared:…` without an `ssl_session_ticket_key` file | Uninitialised ticket key, session forgery | `CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:L/VA:N/...` 8.3; v3.1 6.5 | medium | 1.23.2 to 1.31.6 |
| CVE-2026-95101 | HTTP/3 with `proxy_request_buffering on` | Data injected into the proxied request body | `CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/...` 6.9; v3.1 5.3 | medium | 1.25.0 to 1.31.6 |

nginx.org rates all five medium, while F5's records score three of them 9.2, critical under CVSS v4.0 (measured). The gap is the precondition. Each bug needs the configuration in the second column, and F5 says the three memory-safety ones crash a worker, with code execution possible only where ASLR is disabled or bypassed (reported). The session-forgery bug can bypass client-certificate verification, so it matters most to mutual-TLS deployments. None needs a login. EPSS on 22 October ranged from 0.00175 to 0.00554 (measured).

F5's workarounds, if you cannot upgrade today: avoid `alias` in that location and avoid `$request_filename`; use named captures in `map` regexes; turn off `aio` or stop serving SSI; load a static key with `ssl_session_ticket_key`, or drop the shared cache (servers with `ssl_session_tickets off` are not affected); and set `proxy_request_buffering off` where HTTP/3 is on. How to check: `nginx -v` for the version, then `nginx -T` to dump the effective configuration and look for those directives. Packages, container images and ingress controllers that bundle NGINX ship on their own schedules, so check the version they actually run (reasoned). The same day, njs 1.0.2 fixed two more CVEs (CVE-2026-101025, CVE-2026-101019) in its XML module; the post did not count them.

### Go: one CVE, and it is eMudhra again

CVE-2026-111943 ([GO-2026-6809](https://pkg.go.dev/vuln/GO-2026-6809)) is in `crypto/x509`'s `Certificate.Verify`. The Go CNA files it under CWE-299, improper check for certificate revocation, and publishes no CVSS score. It affects every Go before 1.26.10 and 1.27.0 to 1.27.2, and is fixed in 1.26.10 and 1.27.3 (measured). Go's [announcement](https://groups.google.com/g/golang-announce/c/66pojueaQek) says only that it is "blocking trust in a small set of intermediate certificates due to specific security concerns around their operation", without naming them. The fix ([CL 851047](https://go.dev/cl/851047)) adds a denylist of eight SHA-256 hashes of public keys. I downloaded the six eMudhra TLS intermediates, `EM DV/OV/EV TLS CA - G3B` and `- G3C`, from crt.sh and hashed their keys: all six are in Go's list (measured). The other two are presumably the two code-signing intermediates; I did not confirm that. So the post's "Go — 1 CVE" and its "eMudhra" line are the same incident, counted twice (reasoned).

Who needs it: Go mostly trusts the system's roots, and Go says the denylist is for "the narrower set of cases" where the system store is not updated (reported). Go links the standard library into every binary, so the fix reaches a program only when it is rebuilt with 1.26.10 or 1.27.3 (reasoned). Check which toolchain built a binary with `go version -m <binary>`, or run `govulncheck` on the source or the binary. Not exploited, not in KEV, EPSS 0.00145 (measured).

### GitLab: twelve CVEs in 19.5.1

All twelve are in the [19.5.1 patch release](https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/) of 21 October. Vectors are CVSS 3.1 as GitLab, the CNA, published them. None is exploited, per GitLab, and none is in KEV (measured).

| CVE | Area (edition) | Class | CVSS 3.1 | Affected from |
|---|---|---|---|---|
| CVE-2026-110264 | Regular expression compiler (CE/EE) | Integer overflow, unauthenticated code execution | `AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H` 10.0 | 7.0 |
| CVE-2026-15723 | OmniAuth-to-LDAP auto-linking (CE/EE) | Improper authentication, account takeover | `AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:N` 8.2 | 10.1 |
| CVE-2026-112212 | OAuth/OIDC discovery endpoints (CE/EE) | Shared-cache poisoning | `AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:L` 7.5 | 18.3 |
| CVE-2026-12664 | GraphQL work item email field (CE/EE) | Token scope not enforced | `AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N` 6.8 | 18.2 |
| CVE-2026-16255 | SAML/LDAP membership lock (EE) | Lock not enforced on older requests | `AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:N` 5.9 | 12.0 |
| CVE-2026-105777 | Internal response headers (CE/EE) | Internal credential exposure | `AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N` 4.3 | 17.6.5 |
| CVE-2026-13319 | Group milestones API (CE/EE) | Missing authorization check | `AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N` 4.3 | 15.10 |
| CVE-2026-112378 | AI Gateway feature header (EE) | Paid AI features without a subscription | `AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N` 4.3 | 17.8 |
| CVE-2026-105711 | Merge request title rendering (CE/EE) | Confidential title leaks through a shared cache | `AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:N/A:N` 3.5 | 15.0 |
| CVE-2026-14288 | Merge request approval policy (EE) | Required approval bypass | `AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N` 3.1 | 17.4 |
| CVE-2026-112326 | Security findings (EE) | Read-only user can delete vulnerability records | `AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N` 3.1 | 17.8 |
| CVE-2026-103515 | Duo admin-lock for Amazon Q (EE) | Group Owner can re-enable a locked AI data flow | `AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:N` 2.7 | 19.2 |

That is one critical, two high, five medium and four low; five are EE only (measured). **The catch is the fixed versions.** GitLab backported only the CVSS 10.0 fix to 18.11.13, 19.0.10, 19.1.9 and 19.2.9. The other eleven are fixed only in 19.3.6, 19.4.3 and 19.5.1. So an instance moved to 19.2.9 this week is clear of the critical bug but still carries all eleven others (measured, from each row's impacted versions). Of those, the two highs are the ones to weigh. CVE-2026-15723 needs a logged-in user and an instance with both OmniAuth SAML and LDAP auto-linking enabled. CVE-2026-112212 needs no login, but it needs a shared cache in front of GitLab and a user who takes part in the flow. The rest need an account and expose or change a limited amount of data. One inconsistency: GitLab's text for CVE-2026-105777 says "an unauthenticated user", while its vector says `PR:L`; the table gives the vector. The checker above reports, for any version, how many of the twelve still apply.

## The KEV additions, 13-20 October

CISA added 15 CVEs between 13 and 20 October, 13 of them from 14 to 20 October (measured). Most are due three days after being added under BOD 26-04; two Plex bugs and the Siemens bug get 14 (measured). CVSS is as the CNA published it. KEV names no threat actors, so neither do I.

**Unauthenticated, internet-facing (patch first):**

- **Ivanti Connect Secure, CVE-2026-104935** (13 Oct). Authentication bypass by spoofing, command execution. CVSS 3.1 8.6, EPSS 0.260 (measured). 22.7R2.14 and earlier are not affected.
- **Cisco Secure Email Gateway, CVE-2026-76519** (14 Oct). Path traversal in AMP attachment handling, arbitrary file write. CVSS 3.1 9.8. Advisory `cisco-sa-esa-afw-zqYJkjxp`.
- **Ahsay AhsayCBS, CVE-2026-105133 and -105134** (14 Oct). Auth bypass chained with OS command injection, up to 10.3.2. VulDB scores the injection 10.0: the week's one exploited **CVSS 10**. EPSS 0.383, the highest here (measured). The vectors mark a PoC as existing.
- **Atlassian Data Center, CVE-2026-21589** (15 Oct). Unauthenticated file read in the web root across Bitbucket, Confluence, Jira, Bamboo, Crowd, Crucible and Fisheye. CVSS 4.0 9.3, EPSS 0.127.
- **BeyondTrust Remote Support, CVE-2026-102764** (16 Oct). Improper origin validation, file operations on the appliance. CVSS 4.0 9.3. Fixed in 26.2.3.

**Authenticated or conditional:** Plex Media Server CVE-2026-96652, -96654, -96655 and -96656 (20 Oct), two SSRFs and a URL injection that chain to an admin file write, fixed in 1.43.3.10861. Windows Shell CVE-2026-96951 (13 Oct), CVSS 3.1 8.8, user interaction, October cumulative update. PAN-OS CVE-2026-0322 (14 Oct), admin code injection on the management interface, CVSS 4.0 8.6. Fortinet CVE-2025-61624 (16 Oct), admin CLI path traversal, CVSS 3.1 5.4.

**Local:** SiteGuard Server Edition CVE-2026-106931 (20 Oct), command injection as root or SYSTEM, CVSS 4.0 8.5. Siemens Software Center CVE-2026-110936 (20 Oct), DLL search path, fixed in V4.0.9.8.

## The AI stack: not a quiet week after all

My first version said the AI stack was quiet. It was not. LiteLLM is an AI-infrastructure supply-chain compromise aimed at exactly the keys an AI team holds, and Railway frames its breach as part of a campaign against AI inference providers. Among CVEs, the one relevant item is **vLLM CVE-2026-114049** (21 October): one client's token-allowlist mask can apply to another client's request. Integrity, not code execution: CVSS 4.0 6.3, CVSS 3.1 3.7, fixed in 0.31.0 (measured). It matters on multi-tenant constrained decoding.

The other AI story: OpenAI is credited on both PHP CVEs and OpenAI Codex Security on the Node one. eMudhra's keys were reportedly first broken with AI-assisted tooling, and Mozilla's local agents recovered them from a one-line prompt. One week is a data point, not a trend. Related here: sandboxing agents in [Perplexity SPACE](/articles/perplexity-space) and [NVX](/articles/nvx), and what a vendor's disclosure can establish in [ZCode, open-sourced](/articles/zcode-disclosure).

## Elsewhere this week

- **Tor exit relays** (reported). More than 300 relays were taken over and turned into exits that intercepted SSH. A researcher counted 333 on 2 October; the Tor Project flagged them on 4 October and none were in the consensus by 5 October ([The Hacker News](https://thehackernews.com/2026/10/attackers-hijacked-over-300-tor-exit.html)). Only password logins over Tor in that window, after accepting a changed host key, were exposed. If that was you, rotate and switch to keys.
- **SafePay ransomware** (confirmed). A 20 October joint advisory from CISA, the FBI and partners says the group has hit at least 600 critical-infrastructure organisations since August 2024 ([CISA bulletin](https://content.govdelivery.com/accounts/USDHSCISA/bulletins/42fd782)). Access is through stolen credentials, brute force and VPN abuse; the asks are MFA, patched edge devices and offline backups.
- **State Bank of India** (reported, via coverage of its exchange filing). On 21 October SBI filed an "Incident involving Data Loss" under SEBI's Regulation 30. After a dark-web leak claim it found 3,897 entries with customer data: names, phone numbers, birth dates, addresses, but no passwords, PINs or OTPs, and no stolen funds ([The Hacker News](https://thehackernews.com/2026/10/state-bank-of-india-confirms-data-leak.html)).
- **Japan's "state of emergency in cyberspace"** (reported, and weaker than the post says). On 9 October Masaaki Taira, head of the National Cybersecurity Strategy Headquarters, used those words at a meeting after breaches at more than 20 Japanese companies. I found no government document formally declaring one.

## Reported only

These claims from the post had no primary source I could find. They stay out of the analysis:

- Asana, GOG and the University of Vienna's webmail going down because of PHP. No coverage I found names them. Austria appears in reporting only as "agencies, universities and news outlets".
- Denmark pulling government sites. AFP's coverage does not list Denmark.
- The Japanese Prime Minister's post reaching "48.8 million people". Coverage gives view counts of 23 to 30 million, which is not the same thing.
- Censys's "about 1.5 million servers". I did not find it.
- eMudhra having issued "over 60 million certificates". eMudhra's own count of certificates needing migration is about 30,000.

## What I could not verify

- Apple's and Microsoft's own notices for their eMudhra blocks. I have only news reports for the dates.
- The root cause of the weak eMudhra keys. eMudhra's script-flaw account is preliminary, and the questions on the bug about HSM generation are open.
- Whether any watchTowr-observed attempt against PHP succeeded. Also the claim that PHP 5 is affected, which comes from watchTowr only.
- Cisco's and Ivanti's per-branch fixed versions; I give advisory ids. BeyondTrust's 26.2.3 comes from the CVE record, as its page returned 403.
- The October Oracle Critical Patch Update. I found no account of its contents.
- The CERT-EU, FBI and NSA wording on PHP, which I have only via coverage.
- LiteLLM's root cause, which the maintainers say is unconfirmed.
- CVSS vectors for nine of Node's ten CVEs. Their CVE records were not public on 23 October, so only Node's high, medium and low ratings exist.
- F5's NGINX K-articles, which need JavaScript. The NGINX Plus versions come from F5's CVE records. nginx.org puts CVE-2026-97629 from 1.23.2, while F5's record says 1.23.3; the table follows nginx.org.
- That the last two of Go's eight denylisted keys are eMudhra's code-signing intermediates. I matched six of the eight.

## What to do on Monday

1. Search every environment and image for `litellm` 1.107.0 and the published indicators. Where found, rebuild and rotate everything the host could reach. First.
2. Inventory PHP everywhere, including appliances and images. Update and **restart the workers**. If you cannot, apply PHP's stopgaps or go offline, as CISA and the NCSC advise.
3. On Railway, TiDB Cloud or Zeabur, rotate the secrets you kept there, at the issuing provider.
4. Upgrade self-managed GitLab, even if you patched on 12 October, to 19.3.6, 19.4.3 or 19.5.1 if you can. The 18.11 to 19.2 backports fix only the CVSS 10.0 bug.
5. Patch the five unauthenticated KEV items, Ivanti and Ahsay first by EPSS, and look for compromise: they were exploited before you heard.
6. Update CA bundles in services and images. Check that nothing you serve chains to `emSign ECC Root CA - G3` before 27 October.
7. Update Node.js to 22.23.4, 24.22.1 or 26.12.1 in every image. That clears all ten of its CVEs. Then find every other Brotli decoder: `Brotli` 1.2.1 or `brotlicffi` 1.2.1.0 in Python images, the distro's libbrotli fix, Envoy, Istio and Bun.
8. Update NGINX to 1.30.6 or 1.31.7, or NGINX Plus to the F5 fixes, after checking `nginx -T` for the five configurations. Rebuild Go binaries with 1.26.10 or 1.27.3.
9. Confirm WordPress is on 7.0.3 or a patched backport. Patch internet-facing Plex, and multi-tenant vLLM.
