v vanemmerik.ai / SUPPLY-CHAIN
Supply Chain Β· Watch Friday Β· 29 May 2026 End-of-day synthesis 4 watches Β· 22 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 β€” Late escalation at 21:00 ET: a 19-advisory audit dump against PraisonAI lands on top of the morning's vm2/Redshift/Gotenberg trio β€” official A2A example reaches unauthenticated `eval()`, `deploy --type api` ships with auth disabled, and Platform's JWT key defaults to a hardcoded `dev-secret-change-me`.

Two stories converge on the same shape today. The morning was vm2 β€” seven coordinated advisories, four CVSS 9.8–10.0, four years of sandbox-escape patches finally collapsing into a deprecate-and-replace moment. The supporting cast carried the rest of the news cycle: a CVSS 9.8 RCE in AWS's `redshift-connector` Python driver via an `eval()` in result processing, Gotenberg's default-unauthenticated `downloadFrom` handler crashable by an anonymous concurrent-map-write panic, Sparkle 2.9.1's XPC-listener spoof plus delta-apply symlink traversal, the axios prototype-pollution batch, and the GitHub CLI tuf-repo token leak.

Late escalation at 21:00 ET: a coordinated 19-advisory audit dump against PraisonAI β€” the open-source LLM agent framework and its multi-tenant Platform API β€” lands between 22:00 and 23:05 UTC. The pattern rhymes with vm2: a project many teams adopted as the fast path to shipping LLM agents turns out to have shipped with `eval()` in the official A2A example, a sandbox escape via `print.__self__`, `deploy --type api` emitting a Flask server with auth disabled by default, and a Platform JWT key that literally reads `dev-secret-change-me` whenever `PLATFORM_ENV` is unset. Six more advisories against stigmem-node (federation hardening β€” auth-disabled-but-not-loopback-scoped, cleartext peer transport) and six against Admidio (documents-files.php IDOR, CSRF on PKCS#12 export and SSO toggles) round out the night. authentik's cross-line SAML XMLSig backport remains the day's bright spot β€” three release trains patched on the same day is the discipline the rest of this list needed.

β†’ Operational priority for the night if you deployed PraisonAI via the documented `deploy --type api` command, your endpoint is almost certainly unauthenticated right now β€” take it offline, then rotate any JWTs issued by a Platform instance with `PLATFORM_ENV` unset and grep your config for the `dev-secret-change-me` literal. After that, rip vm2 out of every Node service still running it (no patch exists; the replacement is isolated-vm) and upgrade redshift-connector to 2.1.14 before Monday's first scheduled job.

21:00 ET Β· Last Watch

PraisonAI agent framework + multi-tenant Platform: 19-advisory audit dump at 22:30 UTC β€” unauth `eval()` execution, sandbox escape, `deploy --type api` ships with auth disabled, hardcoded `dev-secret-change-me` JWT key in production

Coordinated 19-advisory audit dump lands against PraisonAI (the open-source LLM agent framework) and its multi-tenant Platform API between 22:00 and 23:05 UTC. Ten advisories hit the core framework, nine hit Platform; seven are CVSS-equivalent critical. GHSA-vg22 (critical): the *official* A2A example exposes an unauthenticated endpoint that reaches LLM-driven `eval()` tool execution β€” a model can be prompt-injected into shelling out on the host. GHSA-4mr5: sandbox escape via `print.__self__` builtins module leak in `execute_code` subprocess mode β€” the standard Python `__self__` backdoor that PyPI-sandbox authors keep rediscovering. GHSA-8444: `praisonai deploy --type api` emits a Flask server with authentication disabled by default; anyone who ran the documented quickstart command and exposed the result is unauthenticated-RCE. GHSA-86qc: call server exposes unauthenticated agent listing, invocation, and deletion when `CALL_SERVER_TOKEN` is unset β€” same default-no-auth-and-no-warning pattern. GHSA-78r8: arbitrary code execution via unguarded `spec.loader.exec_module` in `agents_generator.py`, explicitly noted as a sibling of CVE-2026-44334 (so the prior fix was incomplete). On the Platform side, GHSA-3qg8 ships a hardcoded JWT signing key (`"dev-secret-change-me"`) that's used in production whenever `PLATFORM_ENV` is unset β€” token forgery for any user, anywhere. GHSA-h8q5 and GHSA-c2m8 are cross-workspace IDOR + member-role privilege escalation: any workspace member can promote themselves or anyone else to owner via `PATCH /workspaces/{id}/members/{user_id}`. The remaining items are auth-bypass / cross-workspace IDOR variants on label, dependency, member, and activity-log endpoints. **Operational read:** this is the agent-framework equivalent of the vm2 mass-disclosure earlier today β€” a project that many teams adopted as the fast path to shipping LLM agents turns out to have shipped with eval(), no auth, and dev secrets in production. If you deployed PraisonAI via the documented `deploy --type api` command, your endpoint is almost certainly unauthenticated right now. Take it offline tonight, rotate any JWTs issued by a Platform instance with `PLATFORM_ENV` unset, and grep your tenant for any `"dev-secret-change-me"` literal.

stigmem-node six-advisory federation hardening drop: auth-disabled deployments grant anonymous access beyond loopback, cleartext federation transport, unsigned-plugin override without second-acknowledge

Six advisories against stigmem-node land alongside the PraisonAI batch β€” same audit-dump rhythm, smaller blast radius. The pattern is the recurring federation-server problem: GHSA-fp6w (critical) is the headline β€” when auth is disabled, the server doesn't restrict to loopback, so anonymous access is granted across the network. GHSA-9vp8 and GHSA-jmfc (critical) cover peer-registration without out-of-band approval and federation transport that may fall back to cleartext outside loopback. GHSA-w7pm: unsigned-plugin override could be enabled without an explicit second acknowledgment β€” exactly the consent-bypass pattern that turns "I tested it once with the flag" into "I've been running unsigned plugins for three months". GHSA-9pc9 and GHSA-xh5j are defensive cleanups (Postgres identifier quoting, peer-token timestamp validation). If you run a stigmem-node instance, audit the auth posture before bed: if `auth_disabled` is set, scope it to loopback only, and verify your federation peers are reaching you over TLS.

formie (CraftCMS plugin): unauthenticated front-end submission editing can overwrite existing submissions

verbb/formie, the dominant form-builder plugin for Craft CMS, allows unauthenticated front-end submission editing β€” an attacker can reference an existing submission ID and overwrite the original record. Practical impact depends on what your forms collect (contact records, support tickets, registration data, payment metadata) and what downstream automations trigger on form-submission edit events. Patch line is in the advisory; in the meantime, if you ship Craft+formie, audit whether your handler-side code distinguishes "new submission" from "edit of submission N" before triggering side effects.

Admidio web CMS audit: six advisories on documents-files.php IDOR (cross-folder read/rename), inventory-field deletion by any user, session IDs logged in cleartext, CSRF on SSO client toggles and PKCS#12 export

Six advisories against Admidio (the open-source member-management web app many clubs and small nonprofits run). The two highs (GHSA-x628 and the incomplete-fix follow-up) are IDOR in `documents-files.php` β€” a folder-uploader can use `mode=move_save` and the rename action to read and rewrite files across folder boundaries. GHSA-xw54 is the same #2024 incomplete-fix pattern: any logged-in user can hit `mode=field_delete` to remove inventory fields. The remaining items are housekeeping but worth noting: GHSA-mch8 logs session IDs and auto-login cookie values to the application log (anyone with log access escalates to session theft), GHSA-4rgq (PKCS#12 export) and GHSA-xg76 (SSO client enable toggle) are CSRF-without-tokens on actions that very obviously need them. Upgrade to the patched line and rotate logs if any contain the cookie/session pattern.

18:00 ET Β· First Watch

Seven vm2 / NodeVM advisories drop together: four CVSS 9.8–10 sandbox escapes, plus host RCE via NodeVM denylist gap β€” no fix, library abandoned since 2023

Seven advisories drop against the vm2 npm package in one coordinated batch β€” four CVSS 10s, two highs, one low β€” and NodeVM (which ships in the same package) picks up its own critical alongside. GHSA-6j2x: a JSPI-backed Promise `.finally()` species bypass that reaches host `process` via the constructor chain of a host-originated TypeError when the runtime exposes WebAssembly.promising. GHSA-m4wx: the patch for CVE-2023-37903 used a strict equality check (`options.require === false`) that's trivially bypassed by simply omitting the `require` option β€” `nesting: true` then reaches full RCE. GHSA-76w7: the localPromise constructor change forgot a `resetPromiseSpecies` call, so a custom promise's reject method exposes a raw host error. GHSA-v6mx: `Buffer.call.call({}.__lookupGetter__, Buffer, '__proto__')` plus Node's `ERR_INVALID_ARG_TYPE` reaches the host TypeError constructor. GHSA-rp36 (NodeVM, CVSS 10): the dangerous-builtin denylist misses `process` and `inspector/promises` β€” `require('process').getBuiltinModule('child_process')` works even when child_process is excluded, and `inspector/promises` exposes Runtime.evaluate in the host. GHSA-c4cf and GHSA-m5q2 are highs in the Bridge Proxy (set-trap receiver ignored, missing symbol checks on cross-realm Symbol.for keys). **vm2 has been deprecated since 2023 and there is no patched version.** The documented replacement is isolated-vm (process-isolated, what you actually want as a security boundary). Node's built-in `vm` module is explicitly NOT a sandbox β€” only safe for trusted code. If your product runs untrusted user code in vm2, this is a paging event.

amazon-redshift-python-driver ≀ 2.1.13: CVSS 9.8 RCE via eval() injection in query-result processing

AWS-maintained `redshift-connector` Python driver (≀ 2.1.13) passes server-supplied data through `eval()` during result processing. A rogue server implementing the PostgreSQL wire protocol β€” or a MITM on an unencrypted connection β€” ships a crafted response that lands as arbitrary code in the client process, with the privileges of whatever runs the connector. Patched in 2.1.14. Practical exposure: anywhere a client can be steered at a non-Redshift endpoint (DNS hijack, dev pointed at the wrong cluster, IAM-misconfigured cross-account access) or where SSL verification has been disabled. Upgrade the driver everywhere, then verify every connection string requires `sslmode=verify-full` β€” the latter would have neutered this CVE entirely. AWS-managed CVEs are rare; treat the upgrade as same-day.

Gotenberg ≀ 8.32.0 triple: unauthenticated remote DoS via concurrent-map-write, IPv6 6to4/NAT64 SSRF deny-list bypass, Windows-separator zip path traversal

Three advisories against Gotenberg ≀ 8.32.0, the headless-Chromium PDF rendering service that many SaaS backends shell out to for document export. GHSA-vp73 is the urgent one: concurrent goroutines write a shared map in multipart `downloadFrom` handling without synchronization, and the Go runtime aborts the process with `fatal error: concurrent map writes`. In the default configuration `downloadFrom` is enabled and authentication is disabled, so an unauthenticated remote attacker can crash any exposed instance. GHSA-86m8: the `IsPublicIP` deny-list misses IPv6 6to4 (`2002::/16`), NAT64 (`64:ff9b::/96`), and site-local prefixes that map back to private IPv4 ranges β€” the same NAT64 SSRF class CC-Tweaked and local-deep-research hit this week. GHSA-hwc4: zip upload entry names with Windows-style backslash separators traverse outside the extraction directory. Upgrade past 8.32.0 tonight and put any internet-facing instance behind a reverse proxy with auth β€” the default-no-auth posture has aged badly.

Sparkle ≀ 2.9.1 pair: post-stage-1 XPC listener accepts any local connection; binary-delta intermediate-symlink traversal turns a stolen signing key into root file write

Two advisories against Sparkle 2.9.1 β€” the Mac update framework vendored into thousands of independently distributed macOS apps. GHSA-g3hp: after `_performedStage1Installation = YES`, the AppInstaller XPC listener at the `<bundleId>-spki` Mach service accepts new connections from any local process without team-ID or code-signing checks. The race window is real but tight β€” the original app has to crash or be force-quit between unarchive and `SPUSentUpdateAppcastItemData` β€” and the payload is spoofed appcast-item data to mis-attribute the install. GHSA-hg88: binary delta apply checks for `..` in relative paths and rejects writes whose immediate parent is a symlink, but doesn't detect symlinks deeper in the relative path; a malicious .delta whose archive content drops an intermediate symlink reaches arbitrary file write via the kernel's path-resolution. Exploitation requires a .delta that passes EdDSA signature verification β€” i.e., a stolen signing key β€” but with AppInstaller running as root for system-domain installs, that turns a key-compromise from "replace the bundle" into "write anywhere on disk as root." Bump Sparkle in any app you ship, and audit vendored copies β€” Sparkle gets vendored at high rates.

authentik SAML Source ACS vulnerable to XML Signature Wrapping β€” fix back-ported across three release lines (2026.5.1 / 2026.2.4 / 2025.12.6)

Classic XML Signature Wrapping: authentik's SAML Source ACS trusts the verified signature to belong to the assertion it later reads, but a crafted SAML response makes verification succeed against the attacker's original signed assertion while authentik consumes a sibling assertion containing a victim identifier. An attacker with any account at the upstream IdP completes a normal login, captures their own signed response, restructures the XML, and re-submits it to authenticate as another federated user. Affects deployments using SAML Source for upstream federation with signed assertions, or signed responses without signed assertions. Patched cleanly across three release lines β€” 2026.5.1 (current), 2026.2.4 (previous LTS), 2025.12.6 (older LTS). Bright spot of the day: the back-port discipline is the right shape for an identity provider. Still upgrade tonight if you federate via SAML.

russh 0.34.0–0.61.0: post-decompression SSH packet size unbounded β€” small compressed packets expand to memory exhaustion

russh enforces the SSH packet-length limit on the on-wire size but not on the size after RFC 4253 compression. A remote peer can ship a packet that's reasonably sized on the wire and expands into a much larger message body, which `Decompress::decompress()` grew its output buffer to accept. Effect today: remote DoS / resource exhaustion on the receive path; before 0.58.0 the same path used `CryptoVec`, which makes the historical impact worse. Affects both client and server roles. Upgrade to 0.61.1; on internet-facing endpoints, consider disabling compression entirely as defense-in-depth β€” the bandwidth savings rarely justify the parser-complexity tax in 2026.

Paired Rust tar parsers (`tar` ≀ 0.4.45 and `astral-tokio-tar` ≀ 0.6.1) apply PAX headers to the wrong entry β€” stream desynchronization enables differential extraction

Both the standard `tar` crate and astral's `astral-tokio-tar` apply PAX extended headers to the literal next entry in the stream rather than to the next file entry as POSIX prescribes. A crafted `x β†’ L β†’ file` sequence (PAX header β†’ GNU longname β†’ file) ends up with the PAX `size` extension applied to the longname, desynchronizing the stream so a file extracts differently in Rust than in GNU tar / libarchive / busybox. Practical risk: smuggling files past CI/CD content scanners or content-addressable validation that uses a different parser than the consumer. If you extract tarballs from untrusted sources in Rust β€” cargo build scripts, container image inspection, anything in astral's uv/ruff/ty orbit β€” bump both crates.

uv < 0.11.15: malicious wheel can place entry-point executables outside the env scripts directory β€” PATH-shadow attack via console_scripts

uv places generated `console_scripts` / `gui_scripts` entry points according to the name in the wheel metadata without checking that the resulting path stays inside the env's scripts directory. A malicious wheel can write an executable wherever it wants β€” including a directory already on `PATH` β€” shadowing or overwriting a real binary and getting executed the next time the user types its name. Exploitation requires installing the malicious wheel, so the practical surface is wheels pulled transitively by an attacker-controlled package name. Upgrade uv to 0.11.15+. This is the wheel-naming class the Python packaging ecosystem keeps re-discovering (cf. pip's similar history); the install-time invariant should always be "never write outside the env, regardless of what the metadata claims."

Nuxt 3.11–3.21.5: route middleware not enforced when rendering `.server.vue` pages via `/__nuxt_island/page_*` β€” middleware-as-only-auth bypassable

With `experimental.componentIslands` enabled (default in Nuxt 4), every `.server.vue` file under `pages/` is auto-registered as a server island reachable via `/__nuxt_island/page_<routeName>`. Until 3.21.6 that endpoint rendered the page via SSR without instantiating Vue Router, so `definePageMeta({ middleware })` declarations β€” the canonical Nuxt pattern for page-level auth checks β€” never ran. Any app that relies on route middleware as the sole gate for a `.server.vue` page is bypassable: an unauthenticated attacker hits `/__nuxt_island/page_<routeName>_<anyhash>` and gets the server-rendered HTML directly. Upgrade Nuxt; longer-term, defense-in-depth says auth checks belong inside the page's own data fetcher, not in surrounding middleware.

Symfony Twilio SMS notifier never verifies X-Twilio-Signature β€” unauthenticated webhook injection (patched 6.4.40 / 7.4.12 / 8.0.12)

Symfony's Twilio SMS notifier bridge accepts the configured webhook secret in `TwilioRequestParser::doParse()` and then never uses it β€” the parser ignores `X-Twilio-Signature` entirely and returns the decoded payload unconditionally. Any attacker who learns the webhook URL can forge `delivered` / `failed` / `undelivered` events for delivery-metrics fraud, downstream automation triggers, or to disguise actual SMS failures. Patched in 6.4.40, 7.4.12, and 8.0.12. If you rely on Twilio status callbacks for billing, two-factor delivery decisions, or escalation routing, upgrade Symfony and audit logs for the gap window.

12:00 ET Β· Forenoon Watch

Five coordinated prototype pollution advisories against axios β€” MitM, credential theft, proxy bypass, DoS

Five prototype pollution advisories against axios all land today. The two MitM-class issues are the ones to act on: GHSA-35jp (CVSS 8.7, scope:changed) poisons `Object.prototype.proxy` so every axios request routes through an attacker-controlled proxy β€” full traffic intercept, no user interaction required once Object.prototype is polluted. GHSA-pjwm (CVSS 8.6) bypasses the NO_PROXY SSRF guard introduced in v1.15.0 by supplying IPv4-mapped IPv6 addresses (`::ffff:a9fe:a9fe` for the AWS metadata IP), reaching link-local metadata endpoints via the configured proxy. GHSA-3g43 (CVSS 7.0) is credential theft via `Object.prototype.transformResponse` override β€” auth passwords and response bodies exposed to the injected function. Fix: `npm install axios@^1.16.0` everywhere; the patch uses null-prototype config objects and own-property checks in mergeConfig throughout. Axios is ubiquitous β€” treat this as a dependency-wide rollout, not a per-project decision.

GitHub CLI ≀ 2.92.0 forwards GitHub auth token to TUF mirror domains via gh attestation / gh release verify

GitHub CLI ≀ 2.92.0 incorrectly includes the user's GitHub authorization header in requests to TUF repository mirrors β€” specifically `tuf-repo.github.com` (a GitHub Pages domain, not an API endpoint) and external Sigstore CDN hosts β€” when running `gh attestation`, `gh release verify`, or `gh release verify-asset`. All credential types are affected: GITHUB_TOKEN, GH_TOKEN, GITHUB_ENTERPRISE_TOKEN. Run `gh upgrade` immediately and rotate any tokens that may have been forwarded to those endpoints. If you're logging TUF fetches in CI, grep your runner logs for Authorization headers hitting non-api.github.com hosts as a quick exposure check.

Froxlor 2.3.6 triple advisory: root SSH access via SSH symlink, arbitrary shell assignment via FTP API, incomplete zone-file injection fix

Three advisories target Froxlor 2.3.6's privilege boundary simultaneously. GHSA-mq5v (CVSS 8.8): a shell-enabled customer replaces `~/.ssh/authorized_keys` in their home directory with a symlink to `/root/.ssh/authorized_keys`; the next privileged cron sync appends the customer's public key into root's authorized_keys β€” root SSH without credentials. GHSA-gcv3 (CVSS 8.8): the FTP account handler never validates the shell choice server-side against `system.available_shells`, so any authenticated customer can assign `/bin/bash` regardless of what the UI offers; in `nssextrausers` deployments that lands as a real system shell. GHSA-j6fm is an incomplete fix for the DNS zone-injection CVE-2026-30932 β€” LOC/TLSA validators still pass raw input into bind9 zone files. If you run Froxlor hosting stacks, update past commit b34829262dc3 before the next cron window.

HaxCMS ≀ 26.0.0 stored XSS via whitespace-free event-handler bypass in saveNode

HaxCMS's `/system/api/saveNode` endpoint uses regex-based HTML sanitization that requires whitespace before event-handler attributes. Submitting `href="#"onclick=` (no space) passes the filter and stores the payload in the generated page files, executing on user click. Authenticated write access is required, so the practical threat is a compromised editor account or a CMS instance with self-registration enabled. Patch if you run HaxCMS; otherwise restrict who can edit pages.

Shamefile ≀ 0.1.6 arbitrary file read via untrusted shamefile.yaml in `shame next`

Path traversal in `shame next` lets an attacker-controlled `shamefile.yaml` exfiltrate arbitrary host files one line at a time to the running terminal. The package ships for pip, npm, and Rust simultaneously, so exposure is broader than a single ecosystem. If you accept external shamefiles in CI or automated workflows, upgrade to 0.1.7 and restrict `shame next` to trusted inputs.

local-deep-research < 1.6.10 SSRF bypass in safe_get via urlparse/requests parser disagreement

Classic parser-disagreement SSRF: local-deep-research validates URLs with urlparse against a host blocklist, then sends the actual request via `requests.get`, which can interpret the same URL differently β€” allowing SSRF to reach cloud metadata services (AWS IMDS, GCP metadata, Azure managed-identity endpoints). LDR is common in AI-assisted research pipelines and often deployed with credentials in the environment. Upgrade to 1.6.10+.

06:00 ET Β· Morning Watch

Kimsuky deploys 'HTTPSpy', adds HelloDoor backdoor and abuses VS Code tunnels for C2 against South Korean targets (Mar–Apr 2026)

North Korean APT Kimsuky (Velvet Chollima) ran a March–April 2026 campaign against South Korean military and corporate targets using spoofed security-product installer pages and a fake Webex meeting lure to deliver HTTPSpy, a new HelloDoor backdoor, and β€” the part worth noting β€” VS Code remote tunnels for C2. Not a direct open-source supply-chain compromise, but the VS Code tunnel TTP rhymes with the Nx Console / TanStack pattern from earlier in the week: legitimate developer infrastructure used as the covert channel because the egress looks like normal dev traffic. If your environment doesn't already block or alert on `code tunnel` / `code-tunnel` processes phoning home to `*.tunnels.api.visualstudio.com`, add it β€” the detection is one EDR rule and it covers both the APT use and the next round of npm/extension-marketplace incidents that follow the same playbook.

Hacker News combines yesterday's Sicoob NuGet writeup with an npm cloud-secrets-targeting tranche under one headline

Reader-facing recap of the Sicoob.Sdk NuGet impersonator (covered in detail yesterday from Socket primary) bundled with a separate npm thread about packages designed to harvest cloud secrets. The Sicoob half is unchanged β€” still PFX certs exfiltrated over a Sentry DSN. The npm-cloud-secrets half is the part to read for; the forenoon pass should pull the primary Socket/Phylum writeup if one exists so we can name the package set and the targeted cloud APIs (AWS metadata, GCP service-account JSON, or Azure managed-identity β€” each implies a different remediation surface). For now: nothing new to action on Sicoob beyond yesterday's guidance.