v vanemmerik.ai / SUPPLY-CHAIN
Supply Chain · Watch Wednesday · 26 August 2026 End-of-day synthesis 4 watches · 35 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 — A live PyPI credential-stealer campaign and an unauthenticated LIMS RCE land the same day the MCP-tooling ecosystem's trust-boundary bug spreads to a seventh project.

A stolen long-lived PyPI token turned into two trojanized pantheon-agents releases and eight flagged sibling packages, while a two-request PoC gives anonymous callers Python execution on any unpatched senaite.core lab system. Both are real damage today, not narrative risk.

Underneath them, the MCP-tooling ecosystem keeps failing the same way for a second straight day — Chainlit's unauthenticated MCP command-injection/SSRF pair, mcp-contextforge-gateway's unsandboxed Jinja2, browse-mcp's and consciousness-explorer's unconfined file writes, genieacs-mcp's DNS-rebinding bypass of loopback auth, and utcp-http's unchecked OAuth tokenUrl are seven distinct projects making the same trust-boundary mistake. gRPC Erlang's binary_to_term RCE plus its three-advisory hardening batch, and a Kyverno CEL privilege-escalation bug, round out a day that's unusually heavy on both supply-chain and platform-control-plane risk. CISA's KEV catalog added a Citrix NetScaler memory-safety bug today alongside a batch of five older Red Hat, Microsoft, and .NET-component CVEs — a reminder that active exploitation doesn't require a new vulnerability, just an unpatched old one.

→ Operational priority for the night pull pantheon-agents 0.6.1/0.6.2 off every host before shift end, rotate every credential that machine ever touched, and grep your MCP-tooling deployments for caller-controlled file paths, session IDs, or OAuth tokenUrl fields before the pattern claims an eighth project.

18:00 ET · First Watch

CISA KEV: Citrix NetScaler ADC/Gateway memory-safety bug added to the catalog (CVE-2026-8452)

CVE-2026-8452 landed on the KEV catalog today: an out-of-bounds memory-buffer flaw in NetScaler ADC and NetScaler Gateway that CISA confirms is being actively exploited, with impact limited to denial of service rather than code execution. NetScaler sits at the network edge of a lot of enterprise environments, so a confirmed-exploited DoS there is an outage risk even without an RCE chain. Patch per Citrix's advisory before the 2026-08-29 due date — don't wait for a follow-up RCE writeup to treat this as urgent.

CISA KEV batch-adds five older CVEs: Microsoft SQL Server RCE, a Linux kernel OOB write, and three EOL/legacy component bugs

CISA added five vulnerabilities to KEV in today's sweep, all pre-dating this year: a 2019 Microsoft SQL Server remote-code-execution bug (CVE-2019-1068), a 2022 Linux kernel out-of-bounds write (CVE-2022-0995), a 2021 Ajax.NET Professional deserialization RCE (CVE-2021-23758), and two 2015 Red Hat privilege-escalation bugs in libuser and ABRT. KEV addition means active exploitation is confirmed now, regardless of the CVE's age — the two RCE-class bugs (SQL Server, Ajax.NET Professional) are the ones worth checking your inventory against tonight. Ajax.NET Professional in particular is flagged as likely end-of-life: if you still have it running, that's the actual finding — retire it.

LibreNMS: legacy templates render unescaped SNMP/syslog data — stored XSS from a device you monitor

Multiple legacy PHP templates in LibreNMS output SNMP-polled fields (ifAlias, mempool/storage descriptions) and syslog program names straight into HTML without escaping, so a compromised or spoofed device you're monitoring can plant JavaScript that runs in an authenticated admin's browser the next time they view the alert or health pages. It's a stored XSS that starts on the wire, not in the UI — anything with write access to SNMP or syslog data reaching LibreNMS is now a partial foothold into the monitoring console itself. Patch to 26.5.0+.

SunEditor Embed plugin: crafted iframe-then-script HTML bypasses sanitization for DOM XSS

The Embed plugin's sanitizer only checks the iframe element; a <script src=...> placed right after it gets rebuilt as a live DOM node and executes, so any app that stores or renders SunEditor content without its own backend sanitization gets stored or reflected XSS from crafted rich-text input. If your CMS or ticketing tool lets untrusted users submit SunEditor content, patch past 3.1.3 or add backend HTML sanitization — don't rely on the editor's own cleanup alone.

Cloudreve WebDAV: a scoped DAV credential can traverse out of its configured root via URL-encoded '..'

Cloudreve's WebDAV handler joins the request path onto the credential's configured root without a containment check, and Go's net/http decodes %2e%2e before the handler sees it, so a DAV credential scoped to one folder can read, write, or delete files elsewhere in the same user's namespace. It doesn't cross user boundaries — DBFS ownership checks still hold — but it defeats the entire reason scoped DAV accounts exist: delegating limited access to a sync client or a third party. Patch before trusting any scoped DAV credential as a hard boundary.

@logtape/syslog: unescaped newlines and unvalidated SD-NAME keys enable syslog log injection

With includeStructuredData enabled, @logtape/syslog escapes backslash/quote/bracket in structured-data values but not newlines — and TCP syslog uses a bare newline as the frame delimiter, so an attacker-controlled value containing '\n' plus a fake RFC 5424 header forges an entire second, authentic-looking log record downstream. It's opt-in (non-default), but any pipeline feeding attacker-influenced strings into structured syslog fields should treat this as a log-integrity bug, not just log noise. Check your SIEM ingestion for anything relying on frame boundaries it doesn't independently verify.

IzPack: unsigned installer JARs can path-traverse pack entries to write files outside the install directory

UnpackerBase resolves each pack entry's target path with only separator normalization — no canonical-path or containment check — so a trojanized installer JAR (IzPack JARs carry no signature by default) can plant files at attacker-chosen locations under the victim's privileges, including startup folders and PATH directories. This is the installer-supply-chain shape: the danger isn't the library's own code, it's what a malicious redistributor can smuggle inside a build made with it. If you distribute software via IzPack, sign your JARs and tell users to verify; there's no patched version yet for the underlying traversal.

http4s: HPACK-bomb HTTP/2 denial of service on the Ember backend

Ember concatenates HTTP/2 header and continuation frames before decoding, so a small HPACK-compressed payload expands to a large in-memory header list; roughly five concurrent connections against a 2GB heap is enough to OOM the process. Any http4s server or client running Ember with HTTP/2 enabled and exposed to untrusted traffic is affected — the same HPACK-bomb bug class that's hit other HTTP/2 stacks this year. Disable HTTP/2 on Ember or patch as soon as a fixed release ships; no workaround is listed yet.

Budibase: a low-privilege BASIC-role user can mint arbitrary S3 pre-signed upload URLs using the workspace's stored credentials

POST /api/attachments/:datasourceId/url lets the caller pick the bucket and key and hands back a signed PUT URL backed by the datasource's server-side S3 credentials, with no check that the requesting BASIC-role user should be able to write there. A low-privilege published-app user can therefore write attacker-chosen objects into whatever bucket the workspace's S3 datasource can reach. Patch past 3.39.7, and audit any S3 buckets Budibase workspaces have touched for objects nobody remembers uploading.

asyncssh's fix for the last AuthorizedKeysFile %u bug was incomplete — a leading ~ still escapes the per-user directory

Companion to today's asyncssh SCP path-traversal advisory: the guard added for CVE-2026-45309 blocks '/', '\\', and '..' in the username before %u substitution, but not a leading '~' or '${ENV}', both of which get re-expanded later and land back on the file-open call — defeating the fix. If you patched the earlier AuthorizedKeysFile bug and considered it closed, it isn't; wait for the real fix or add your own username allowlist in front of it.

cakephp/debug_kit: MailPreview's unsafe reflection allows arbitrary constructor execution — dev-mode only

DebugKit's MailPreview feature builds objects via unchecked reflection, so an attacker who can reach it with debug mode on and a matching local/allowlisted hostname can trigger arbitrary constructor execution. It only bites if DebugKit ships into a build with debug mode left on — the real fix is making sure it's a dev-only dependency and debug is off in prod. Audit your prod bundles for debug_kit leaking in from a shared composer.json.

OpenWISP IPAM: subnet CSV export skips the org-membership check its import sibling has

ExportSubnetView loads a subnet by ID with no organization filter, while the matching import endpoint does check membership — so any authenticated user in one tenant can export another tenant's subnet CIDR, name, and every IP address in it. Classic asymmetric-authorization bug: someone wrote the check once and didn't copy it to the mirror endpoint. Patch past 1.2.0.post1, and grep your own multi-tenant CRUD pairs for the same missing-on-one-side pattern.

AsyncHttpClient's shared cookie store lets one host plant a cookie scoped to another domain

ThreadSafeCookieStore stores a response's cookie under whatever Domain attribute it claims, without checking the responding host is allowed to set cookies for that domain — a classic cookie-tossing gap. It only matters if your app shares one AsyncHttpClient (and its cookie jar) across a trusted backend and anything attacker-influenced — link previews, webhook fetchers, and SSRF-prone URL fetchers are the obvious cases. Fixed in 3.0.11/2.16.0; until then, give attacker-reachable fetches their own client instance and cookie store.

Starlette-Admin: unvalidated order_by/search params bypass the UI's field allowlist

The admin UI restricts which fields are sortable or searchable, but the backend never re-checks that allowlist against API requests, so an authenticated user can sort or filter on fields never meant to be exposed, or crash the endpoint with an HTTP 500 by supplying a Python dunder name like __class__. It's an authenticated info-exposure oracle plus a minor DoS, not a break-in — patch to 0.16.1 on your normal cadence.

Wasmtime: WASIp1 fd_renumber leaks a host file descriptor on every call

fd_renumber updates the guest's descriptor table but not the host's, so a wasm guest looping the syscall exhausts host file descriptors until the Store is destroyed — a resource-exhaustion DoS, not a sandbox escape, and only in runtimes exposing native file access. Low severity, but if you're running untrusted wasm modules with filesystem access, patch to the fixed line release on your normal cadence.

kas (Yocto/BitBake build tool) persistently disables SSH host-key checking for the invoking user

When kas sets up an SSH key from SSH_PRIVATE_KEY and finds no existing ~/.ssh/config, it writes one with a global 'Host * / StrictHostKeyChecking no' — meant to smooth over CI runners with no known_hosts, but the setting outlives the kas invocation and weakens every future SSH connection that user makes. CI runners that reuse a persistent home directory across jobs are the exposure; ephemeral runners are fine. Fixed in 5.4 — check any long-lived build agent's ~/.ssh/config for a stray 'Host *' block kas left behind.

OpenSTAManager: unsanitized group-name field allows HTML injection in the admin UI

A privileged user creating a user group can inject an anchor tag into the group name, which then renders live in the group list and on any user assigned to that group — useful for phishing or unintended redirects inside the admin console, not code execution. Requires an already-privileged account and another user's interaction, so it's a low-priority fix on your normal cadence.

Nimbus Manticore (Iranian IRGC-linked APT) expands toolset with a TWOSTROKE-like backdoor and SSH tunneler

Group-IB reports new infrastructure and two previously undocumented tools — a TWOSTROKE-style backdoor and an SSH tunneler — from Nimbus Manticore, an IRGC-affiliated group researchers call among the most active Iranian APTs this year. It's an espionage-focused APT report rather than a direct supply-chain attack, but the SSH-tunneler-plus-dormant-backdoor toolkit shape rhymes with the persistence techniques showing up in dependency-poisoning campaigns — useful context if you're hunting for lateral movement, not a tonight action item.

12:00 ET · Forenoon Watch

Trojanized pantheon-agents 0.6.1/0.6.2 on PyPI ship a credential stealer — Hades/Mini Shai-Hulud lineage

A stolen, long-lived PyPI API token was used to push two trojanized releases of pantheon-agents directly to PyPI; the payload is a `*-setup.pth` file that runs on interpreter startup, pulls down the Bun runtime, and exfiltrates `.pypirc`, `.npmrc`, AWS credentials, and SSH keys. GitHub attributes this to the June 2026 "Hades" campaign (Mini Shai-Hulud/Miasma lineage) and flags eight sibling projects from the same maintainer as also compromised. If you installed 0.6.1 or 0.6.2, assume every credential on that machine is burned — uninstall, check for `~/.bun` and a stray `_index.js`, and rotate everything.

senaite.core: unauthenticated eval() RCE in the Plone LIMS platform's JSON API (CVE-2026-54569)

Two chained bugs — a missing permission check on the JSON API's update route and an `eval()` call on RecordsField values — let any anonymous network caller run arbitrary Python on the Zope worker, with a working two-request PoC against a stock senaite/senaite:v2.6.0 container. SENAITE is a lab information management system used by medical and diagnostic labs; full ZODB read/write and the ability to mint admin accounts follow directly from the RCE. Patch off 2.x now, or firewall `/@@API` and `/manage` until you can.

Chainlit: unauthenticated command injection via MCP stdio transport (CVE-2026-45018), patched in 2.12.0

When `features.mcp.enabled = true`, Chainlit's `/mcp` endpoint allowlists the executable name in a client-supplied `fullCommand` string but never inspects the arguments, so `npx -y -c '<shell command>'` clears the allowlist and runs whatever the attacker specifies. MCP has been off by default since 2.7.0, so exposure is limited to deployments that opted in — but 2.12.0 removes client-supplied commands entirely rather than trying to patch the allowlist. If you run Chainlit with MCP enabled, upgrade; the MCP server config format changes in the process.

Chainlit: same-day SSRF via MCP SSE/streamable-http transports (CVE-2026-45019)

Companion advisory to today's Chainlit MCP RCE: a client-supplied `url` and `headers` dict on the SSE/streamable-http MCP transports let an unauthenticated caller make the server fetch arbitrary internal URLs — including cloud metadata endpoints — while forwarding attacker-set `Authorization`/`Cookie` headers. Same 2.12.0 patch, same MCP-must-be-enabled precondition as the RCE above. If you're already patching one, you're patching both.

Kyverno 1.18.x: CEL generator.apply() lets a namespaced tenant write into kube-system

A NamespacedMutatingPolicy's `matchConditions` CEL expression can call `generator.apply("kube-system", ...)`, and the admission controller creates the resource there under its own cluster-wide RBAC because the namespace argument is never checked against the policy's own scope. A tenant who can only create policies in their own namespace can therefore write ConfigMaps, Secrets, or RoleBindings into kube-system — a clean privilege-escalation primitive with a working PoC. Audit who can create NamespacedMutatingPolicy objects now; no patched version is listed yet.

gRPC Erlang: unsafe binary_to_term on the wire — atom-exhaustion DoS or RCE via decoded funs (CVE-2026-48853)

`GRPC.Codec.Erlpack.decode/2` calls `:erlang.binary_to_term/1` without `:safe` on raw request bodies, so a crafted payload either exhausts BEAM's atom table and crashes the whole node, or — if the decoded value reaches a call site that applies it — executes as arbitrary code in the server process. Only bites servers that explicitly register the Erlpack codec, but if you did, it's unauthenticated: any peer that can reach the gRPC endpoint qualifies. Drop the Erlpack codec or patch immediately; see the related batch below.

@arikusi/deepseek-mcp-server: caller-controlled session_id lets any client hijack another's chat session (CVE-2026-55604)

The MCP server's session store looks up conversations by a client-supplied `session_id` with no binding to an authenticated principal, and the `deepseek_sessions` tool lets an attacker enumerate active IDs before reusing one in `deepseek_chat`. No credentials required — anyone who can call the MCP tools can read and continue someone else's conversation. Patched in 1.7.0; upgrade if this server is exposed to more than one trusted caller.

mcp-contextforge-gateway: unsandboxed Jinja2 in prompt templates is SSTI-to-RCE for anyone who can register a template

The gateway renders user-supplied prompt templates with Jinja2's plain `Environment()` instead of `SandboxedEnvironment`, so an authenticated user with template-registration rights can store a payload that executes arbitrary Python on the gateway host at render time. No patched release exists yet — the fix is only on the unreleased main branch — so restrict who can register or update prompt templates until it ships. Same lesson as every SSTI advisory: sandboxing isn't optional once the template author isn't fully trusted.

browse-mcp ≤0.8.1: unconfined save/state paths let an MCP caller — or a prompt-injected agent — write files anywhere the process can reach

`browser_download` and `browser_save_state`/`browser_load_state` honor a caller-supplied path with no confinement, so a malicious MCP client — or an autonomous agent steered by indirect prompt injection on a page it visited — can write attacker-controlled bytes to `~/.bashrc`, a cron file, or an autostart entry. `force_fetch` separately bypassed the configured origin allowlist. Fixed in 0.8.2, which confines writes under `~/.browse-mcp/` and rejects traversal; upgrade before pointing any browsing agent at untrusted pages.

genieacs-mcp: DNS rebinding reaches the loopback-only MCP listener from a browser tab (CVE-2026-55637)

The Streamable HTTP MCP endpoint trusts caller-supplied Host/Origin headers, so a malicious web page using DNS rebinding can route a victim's browser to the local MCP listener, open a session, and invoke GenieACS tools with no secret required. Auth is only enforced when the listen address isn't loopback — treat 'bound to 127.0.0.1' as no protection at all for a browser-reachable MCP service. Third distinct MCP-trusts-localhost bug logged this month; grep your own MCP deployments for the same assumption.

utcp-http ≤1.1.3: OAuth2 tokenUrl from a remote OpenAPI spec is trusted unvalidated — credential exfil to an attacker endpoint

utcp-http auto-generates tools from remote OpenAPI specs and, unlike its own discovery- and invocation-URL validation, never checks the `tokenUrl` embedded in a spec's OAuth2 security scheme before POSTing the registered `client_id`/`client_secret` to it. Registering an attacker-controlled OpenAPI spec and invoking any OAuth2 tool it generates is enough to exfiltrate credentials — the same tool-generation-from-untrusted-spec trust problem MCP servers keep hitting, just in UTCP's clothes. Validate or pin tokenUrl before a fixed release ships.

consciousness-explorer / sublinear-time-solver: MCP export_state/import_state arbitrary file write (CVE-2026-55609)

The `export_state`/`import_state` MCP tools pass a caller-supplied `filepath` straight to `fs.writeFileSync`/`readFileSync` with no path constraint, so any MCP caller can overwrite files like `~/.ssh/authorized_keys` on the host running the server. The same sink class showed up in the sibling solver's vector save/load tools. Patched in consciousness-explorer 1.1.2 and sublinear-time-solver 1.6.0, which confine writes to a dedicated directory and enforce a basename-only contract.

asyncssh: SCP path traversal to arbitrary file write (CVE-2026-54591)

A crafted filename in an SCP transfer lets the remote side write outside the intended destination directory on the local end — arbitrary file write anywhere the asyncssh process has permissions. asyncssh underpins a lot of Python automation and CI file-transfer tooling; if you accept SCP transfers from anything less than a fully trusted remote, patch before the next run.

phpMyFAQ: GroupController::updatePermissions lets a GROUP_EDIT admin grant their own group full admin rights

A user holding only the narrow GROUP_EDIT permission can call `updatePermissions` and grant their own group the full admin permission set, turning a limited delegated-admin role into complete instance control. No CVE assigned yet — check who holds GROUP_EDIT in your phpMyFAQ instance and patch when a fixed release lands.

gRPC Erlang: three more hardening advisories land alongside today's RCE — gzip bomb, unbounded body accumulation, path-binding override

Same package, same day as the critical binary_to_term RCE above: GHSA-6ccx-9c9f-327w (unbounded gzip decompression — a decompression-bomb DoS), GHSA-q8gf-9rvj-gmgj (unbounded request-body accumulation in read_full_body/3), and GHSA-mwr4-5g34-j5cq (path bindings overridable by query string or request body) read like a full security review pass on the Erlang gRPC package rather than four unrelated bugs. None are independently as severe as the RCE, but they argue for upgrading to whatever release ships all four fixes rather than patching the critical one alone.

Aikido: 'software supply chain security requires decisions rather than defaults'

Opinion piece, not an incident: the argument is that gating, dependency pinning, backporting, and SBOM upkeep all ship with reasonable defaults but no assigned owner, so they quietly rot until an incident forces the issue. Worth five minutes if your org's pinning or SBOM policy has an owner in name only.

06:00 ET · Morning Watch

SLEEPWALKER: dormant Windows backdoor wakes on a single crafted packet, runs a custom bytecode VM

An independent researcher has documented SLEEPWALKER, an unsigned 64-bit Windows DLL (59,904 bytes) built for side-loading into a legitimate host process, that sits inert in memory until one specifically crafted network packet arrives and then executes commands through a custom 23-instruction bytecode VM instead of a stock C2 protocol. No confirmed delivery vector yet, but the side-load-plus-dormant-trigger shape is the same one abused by dependency-poisoning droppers that wait for a signal before unpacking a payload, so it's worth adding to detection rules now rather than after a package-based sighting. Watch for a follow-up naming the loader or install path.