v vanemmerik.ai / SUPPLY-CHAIN
Supply Chain · Watch Saturday · 30 May 2026 End-of-day synthesis 4 watches · 10 items

From the watchtower — what crossed the wire today.

A four-times-a-day standing watch on the open-source supply chain. Each pass pulls newly disclosed CVEs, freshly catalogued KEV adds, and active attacks reported in the wild — then ranks them by severity for the day.

The story of the day — Developers are the day's target — a Ghost CMS RCE has backdoored 700+ tech and university sites into ClickFix droppers, CISA hands PAN-OS a 72-hour patch clock, and another AI-coding CLI ships with implicit working-directory trust.

The day's items don't share a CVE family — they share an intended victim. Engineers, SREs, and the workstations and VPNs that make those people productive are the through-line across a CMS campaign, a federal-clock VPN bypass, and the latest AI-CLI working-directory bug.

Ghost CMS sites that host the blogs and homepages of universities (Harvard, Oxford), AI and SaaS companies, and DuckDuckGo are now serving fake CAPTCHA pages that ask visitors to paste shell commands into their terminal — XLab has 700+ confirmed compromised via CVE-2026-26980, a CVSS 9.4 unauthenticated SQLi that leaks the Admin API key in a single request. CISA's 3-day clock on PAN-OS CVE-2026-0257 tells you what they're seeing in the wild: unauthenticated attackers walking onto the corporate VPN. Ouroboros-ai joins yesterday's PraisonAI in the running list of AI CLIs whose project-local `.env` can override which binary executes on `init` — the same shape, a week apart, in a category of tooling we hand commit-and-run rights inside `git clone`'d directories. The connective thread is trust: Ghost trusted post-publication content not to mutate, PAN-OS trusted its auth state machine, AI CLIs trust the directory they're spawned in. The defensive bright spot is Nezha — its second SSRF in a week, but patched cleanly in 2.0.10 within hours of disclosure.

→ Operational priority for the night patch PAN-OS before the 2026-06-01 CISA deadline, audit any Ghost CMS instance you operate for injected post-article `<script>` tags and upgrade to 6.19.1, and treat any "paste this into your terminal" prompt your team encountered this week as a credential-rotation event.

12:00 ET · Forenoon Watch

Ghost CMS CVE-2026-26980 (CVSS 9.4): unauthenticated SQLi weaponized at scale — 700+ developer and tech community sites backdoored, serving ClickFix malware to every visitor

CVE-2026-26980 is a CVSS 9.4 unauthenticated blind SQL injection in Ghost CMS (v3.24.0–6.19.0) that exposes the site's Admin API key in a single crafted request — no account required — and enables bulk article backdooring via the Ghost Admin API. An XLab-documented exploitation campaign has compromised 700+ websites across universities (Harvard, Oxford), AI and SaaS companies, and DuckDuckGo, injecting malicious JavaScript loaders into published articles that serve fake CAPTCHA (ClickFix) pages to every real visitor, prompting them to paste attacker-controlled shell commands into their terminal. Developers are the downstream targets here — patch Ghost to 6.19.1 immediately, audit your published articles for injected `<script>` tags at page bottom, and if you've executed a browser-prompted 'fix' command this week, rotate all local developer credentials and review shell history.

Exim 4.88–4.99.3 (CVE-2026-48840): PROXYv2 malformed frame leaks 16 bytes of uninitialized stack memory into SMTP banner — ASLR-defeating information disclosure

CVE-2026-48840 (CVSS 5.3) affects Exim 4.88–4.99.3: in PROXYv2 mode, a frame with a TCPv6 address family and a zero-length header causes Exim to skip the data copy but still walk into the IPv6 handling block, silently reading 16 bytes of uninitialized stack union memory into the SMTP banner returned to the connecting host. An attacker with SMTP access to a PROXYv2-fronted Exim instance can probe this repeatedly to map stack layout and defeat ASLR — a useful stepping stone for chaining into a more severe exploit later. Patch to 4.99.4; if immediate patching is blocked, removing the `hosts_proxy` directive from your Exim configuration disables the vulnerable code path entirely.

06:00 ET · Morning Watch

CISA KEV add: Palo Alto Networks PAN-OS authentication bypass (CVE-2026-0257) — actively exploited, lets attackers establish unauthorized VPN sessions

CISA adds CVE-2026-0257 to KEV with a 3-day federal due date (2026-06-01). Palo Alto Networks PAN-OS contains an authentication bypass on the GlobalProtect/VPN path that lets unauthenticated attackers establish unauthorized VPN sessions — i.e., reach the internal network without credentials. The 3-day clock (vs the standard 14) signals CISA is seeing in-the-wild use against federal targets. Practical guidance: apply Palo Alto's mitigation per their advisory tonight, and if you can't patch immediately, restrict GlobalProtect portal access to known source IPs and audit recent GlobalProtect session logs for sessions from IPs that have no business holding one. The bypass primitive is the same shape as CVE-2024-3400 and CVE-2025-0108 from previous PAN-OS auth-bypass cycles — if you wrote detection rules during those incidents, dust them off.

Koel ≤ 9.3.4 SSRF via podcast episode enclosure URLs — unvalidated `<enclosure url>` fetched server-side and streamed back to the user

Koel (popular self-hosted music streamer) validates the podcast feed URL with `SafeUrl` (DNS + public-IP check) at subscription time, but the individual `<enclosure url="...">` values parsed out of the RSS XML are stored verbatim. When a user plays an episode, `Http::sink()->get($episode->path)` downloads the full HTTP response from whatever URL the feed declared and streams it back to the caller. An attacker registers an account, hosts an RSS feed whose enclosure points at `http://169.254.169.254/latest/meta-data/iam/security-credentials/`, subscribes Koel to it, then plays the episode — AWS instance credentials come back as the audio body. Patched in 9.3.5+; this is the same "validate the outer URL, trust the inner URLs" class as the Gotenberg SSRF from yesterday. If you self-host Koel for a team, upgrade tonight — the Community edition is enough to exploit, no Plus license required.

ouroboros-ai < 0.39.0: project-local `.env` overrides CLI path — `git clone && cd && ouroboros` runs attacker code as the user

Ouroboros (Python AI-coding CLI in the same orbit as aider / opencode) loads the project-directory `.env` and honours `OUROBOROS_CLI_PATH`, `OPENCODE_CLI_PATH`, and other backend selectors from it. A malicious repo ships a `.env` with `OUROBOROS_CLI_PATH=./malicious_script.sh`; the moment the user runs `ouroboros init` (or any adapter-instantiating command) in the cloned directory, the script executes with the user's privileges. Patched in 0.39.0 by denylisting execution-affecting variables from project-local `.env` (trusted `~/.ouroboros/.env` still works). Rhymes precisely with yesterday's PraisonAI dump: the AI-agent CLI category keeps shipping with implicit trust of the working directory. If you've handed an AI coder commit-and-run rights inside `git clone`'d directories, audit which CLIs you use for the same class of override — `OURO_*`, `OPENCODE_*`, `CLAUDE_CODE_*`, `AIDER_*`, etc.

python-zeroconf trio: LAN-local memory exhaustion via unbounded DNS record cache, traceback-pinned packet retention, and unbounded recursion in compression-pointer decoder

Three coordinated advisories against `python-zeroconf` (CVSS 6.5 each), the pip-published mDNS implementation that backs Home Assistant, AsyncIO mDNS, and pretty much every Python service that does discovery. GHSA-rfg2: a multicast flood on the LAN fills the DNS record cache without bound. GHSA-phvx: zeroconf's exception-dedup state keeps packet buffers alive via traceback frame locals — a steady stream of malformed packets pins memory until OOM. GHSA-9pgc: unbounded recursion in the DNS compression-pointer decoder turns a crafted single packet into a stack-blowing DoS. All three require LAN multicast reach, so internet-facing impact is nil, but if you run zeroconf on a corporate Wi-Fi or in a hostile co-tenant network (lab, conference, classroom), upgrade. The pattern — "old library, new attacks against LAN-trusted assumptions" — rhymes with the avahi disclosures from late 2025.

Admidio continuation (three more): CSRF-driven arbitrary password reset, dead authz check in modules/categories.php, cross-folder file_delete bypass

Three more Admidio advisories that landed at the tail of yesterday's six-advisory audit (see the 2026-05-29 watch for the documents-files.php IDOR + CSRF cluster). GHSA-mx25 (CVSS 5.2): the `send_login` registration mode resets arbitrary user passwords via CSRF — an attacker-controlled page can force a logged-in admin's browser to reset any account's password to a value the attacker chose. GHSA-rwjr (CVSS 6.5): module-administrators can delete or reorder categories owned by *other* modules because the authorization check in `modules/categories.php` is structurally dead (the condition never evaluates true after a refactor). GHSA-qc4c (CVSS 6.5): the `file_delete` path lets authenticated users without delete privileges remove files from folders they don't control. Same Admidio shape as yesterday — if you run it, this is now nine advisories in 36 hours; treat the codebase as actively-audited and budget the upgrade window.

Nezha < 2.0.10 blind SSRF via DDNS webhook configuration — authenticated low-priv users make the dashboard host issue arbitrary internal requests

Nezha (popular Go monitoring dashboard) already ships SSRF protection on its notification webhook path — IP pinning, scheme allowlist, blocked-CIDR list, no redirects. The DDNS webhook provider (`pkg/ddns/webhook/webhook.go`) was not given the same treatment. An authenticated user creates a DDNS profile with `Provider: webhook`, attaches it to a server they own, triggers a DDNS update (the agent IP-reporting path will do it automatically), and the dashboard host fires off an arbitrary HTTP request with attacker-controlled method, URL, headers, and body. Response body is not returned, so this is blind SSRF — useful for poking internal state-changing endpoints (admin APIs that trust localhost, internal CI triggers) but not for direct credential exfiltration. Patched in 2.0.10. This is Nezha's second supply-chain-adjacent advisory this week (cross-tenant cron RCE landed on the 2026-05-24 watch); if you run Nezha publicly, upgrade and disable DDNS for non-admin users.

Nerdbank.MessagePack pair: inefficient CPU computation and collection-deserialization memory amplification DoS

Two CVSS 5.3 advisories against `Nerdbank.MessagePack`, the .NET MessagePack serializer maintained by AArnott (xUnit, Visual Studio platform). GHSA-92vj: a parser path performs O(n²)-shaped work on attacker-controlled input, turning small inputs into pegged-CPU denial of service. GHSA-qjvr: collection deserialization allocates based on the declared count before reading bytes, so a tiny payload (`[count=2^31]`) immediately consumes gigabytes. Both are the same family of MessagePack/CBOR/Protobuf bugs that the protocol ecosystem keeps rediscovering — declared-length amplification and worst-case-complexity parser paths. If you accept MessagePack from untrusted callers (RPC endpoints, queue consumers), upgrade and ensure your reader-side limits (`MessagePackSerializerOptions.MaximumObjectGraphDepth`, custom `IFormatterResolver` ceilings) are configured.

CC-Tweaked SSRF bypass via NAT64 (`64:ff9b::/96`) — third Java/Go service this week with the same blocklist gap

CC-Tweaked (Minecraft ComputerCraft mod) blocks SSRF with Java's `InetAddress` classification predicates but never checks the NAT64 well-known prefix `64:ff9b::/96` — the prefix isn't `isSiteLocalAddress()` or `isLoopbackAddress()` to Java, so `http://[64:ff9b::0a00:0111]:8888/` reaches `10.0.1.17:8888` on any network with a NAT64 gateway (the default on AWS/GCP IPv6-only subnets since AWS's Feb-2024 IPv4 pricing change). Tagged context because this is a Minecraft mod, not core infrastructure — but it's the third NAT64 blocklist gap this week (Gotenberg yesterday, local-deep-research two days ago), all in libraries that wrote SSRF defenses before NAT64 became routine. If you maintain an SSRF allow/denylist anywhere in Java, Go, or Python, grep for `64:ff9b` — if it's not in your filter, you have the same bug.