v vanemmerik.ai / SUPPLY-CHAIN
Supply Chain · Watch Thursday · 02 July 2026 End-of-day synthesis 4 watches · 28 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 — Six unrelated MCP and agent-gateway projects disclosed authorization or credential-handling bugs in the same 24 hours, making the agent-tooling trust boundary — not any single campaign — today's story.

First Watch locks in the shape of a busy Thursday: thirty items across three passes, four of them newly critical — but the pattern, not any single bug, is the story.

Six unrelated MCP and agent-gateway projects disclosed authorization or credential-handling bugs in the same 24 hours: mcp-memory-service shipped document routes with zero auth guard, Apify's Actor MCP server leaked API tokens via path-authority injection, OpenClaw disclosed thirteen advisories across its approval and scope-inheritance layers, Grackle's MCP tool dispatch fails open on scoped agents, fast-mcp-telegram's Bearer-token check path-traverses past its own session isolation, and 9router shipped with a hardcoded fallback JWT secret. None of these share code or an attacker — they share a maturity gap: agent-facing auth layers keep getting bolted on after the tool-calling surface, not designed in alongside it. Add Mautic's twin 9.9s (SSTI plus path traversal) and LaunchServer's unauthenticated file handler, and today's critical count is the highest of the week.

The bright spot: nothing on today's watch is a confirmed in-the-wild campaign — Socket and Phylum stayed quiet, and CISA KEV added nothing new since yesterday's SharePoint entry. Operational priority for the night: if you run any MCP server — memory, Telegram, Actor, or otherwise — treat "is the tool-dispatch layer actually enforcing scope" as a today problem, not a backlog item.

18:00 ET · First Watch

9router ships a hardcoded fallback JWT secret, plus an unfixed host-header spoof and missing authz on top

9router — an npm-distributed LLM request router — falls back to a hardcoded default JWT signing secret when none is configured, so any deployment that didn't override it accepts attacker-forged tokens outright (CVSS 9.8); a second advisory shows the earlier host-header "local-only" access gate can still be spoofed past its own fix, and a third covers missing authorization paired with OS command injection. Three advisories against one small routing proxy in the same batch means someone went looking hard, and each bug alone is enough for full takeover of whatever backend the router fronts. Set an explicit, random JWT secret before deploying, don't trust Host-header-based access gates at all, and upgrade past the patched releases across all three CVEs.

fast-mcp-telegram's Bearer-token path traversal bypasses its own session-file protections

fast-mcp-telegram — an MCP server exposing Telegram automation to agents — accepts a crafted Bearer token that path-traverses out of the intended session directory, defeating the isolation meant to keep one user's Telegram session file from another's. In an MCP deployment that's session hijacking: whoever controls the token controls the underlying Telegram account the session file authenticates. Same theme as today's mcp-memory-service and Apify Actor-MCP bugs — MCP glue code keeps shipping auth checks that don't hold under adversarial input. Patch and rotate any session files that may have been exposed.

Mautic disclosure batch: server-side template injection in theme templates and path traversal via campaign import, both CVSS 9.9, plus four more

Mautic shipped six advisories together, and two are about as bad as GHSA scoring gets: server-side template injection in theme templates (9.9) that's a straight line to RCE for anyone who can edit or upload a theme, and path traversal via campaign import (9.9) that can write files outside the intended directory. The other four are lower severity but still real — stored XSS in two components, an API v2 authorization bypass, and SSRF in the Focus component. Mautic runs as a marketing-automation platform with broad SMTP and CRM access, so a compromised instance is a credential and contact-list goldmine. Patch to the fixed release now and audit for unexpected theme files or campaign-import artifacts if you can't patch immediately.

LaunchServer's FileServerHandler serves unauthenticated path traversal — read or write any file the process can touch

LaunchServer's FileServerHandler resolves requested paths without normalizing or bounding them against a root directory, so an unauthenticated request with ../ sequences can read or write arbitrary files with the server process's privileges. It's a Minecraft-launcher backend, but the bug shape — auth-free file handler, no path canonicalization — is the same pattern that keeps recurring across unrelated Java/Kotlin services this year. Patch immediately if you run LaunchServer's file-server component facing any untrusted network.

Grackle's MCP tool layer fails open — scoped agents can reach tools and tasks outside their granted scope

Grackle's authorization check for MCP tool invocation fails open on certain error paths, letting an agent scoped to specific tools or tasks instead reach across task and user boundaries. For a multi-tenant agent platform, a fail-open authz check in the tool-dispatch layer is the worst place for that bug to live — it's exactly the boundary meant to keep one user's agent from touching another's data or tools. Upgrade and re-audit scope enforcement anywhere Grackle sits between an agent and its tool set.

Steeltoe disclosure batch: management-port isolation bypass via spoofed Host header, plus six more spanning credential leaks and cache poisoning

Steeltoe — the .NET microservices toolkit — shipped seven advisories at once: a spoofed Host header can bypass the isolation meant to keep the management port separate from the app port (8.2); the environment-variable sanitizer that's supposed to redact secrets misses connection strings, leaking embedded DB passwords through actuator endpoints (7.5); Eureka service discovery poisons its entire registry cache when a single node reports an unrecognized DataCenterInfo.Name (7.5); and four more cover TLS private keys left world-readable in /tmp, a JWKS cache shared and never invalidated across auth schemes, sensitive actuators gated by too-low a permission tier, and an OAEP-to-PKCS1v1.5 padding downgrade. None are remote code execution alone, but stacked together they erode most of the defense-in-depth Steeltoe's actuator/discovery layer is supposed to provide. Patch to the fixed releases and check whether actuator endpoints have ever leaked a raw connection string into logs or monitoring.

SimpleSAMLphp cluster: TLS validator confusion enables cross-IdP authentication bypass, plus an unsigned-response and an XPath DoS bug

SimpleSAMLphp's HTTP-Artifact binding confuses which IdP's TLS validator to apply, letting a valid response from IdP A authenticate as if it came from IdP B in a multi-IdP deployment (8.7) — a real cross-tenant auth bypass for anyone federating multiple identity providers. Alongside it: an SP that accepts a response from an unexpected IdP when the unsigned InResponseTo field isn't checked, and an XPath transform that can be driven into a DoS. SAML libraries are load-bearing infrastructure for enterprise SSO; if you run multi-IdP SimpleSAMLphp, patch and re-verify that responses are matched to the IdP that's actually supposed to have signed them.

Recce's DuckDB-backed query API lets an unauthenticated caller read or write local files through the server process

Recce — a dbt data-diffing tool — exposes its query-run API without authentication by default, and when the backing warehouse is DuckDB, an attacker can use DuckDB's filesystem primitives to read and write files the Recce process can touch, including tampering with dbt artifacts or overwriting served static files for stored XSS. Running Recce as root turns this into root-level file access. Don't expose `recce server` to any untrusted network; upgrade to 1.50.0 and put it behind an authenticated proxy regardless.

Craft CMS: forced element moves can unauthorized-delete destination folders, and bulk duplicate lets mass assignment overwrite existing elements

Two Craft CMS bugs land together: a forced-move operation can delete a destination folder the acting user shouldn't have permission to remove, and the bulk-duplicate action trusts a client-supplied id in newAttributes closely enough that mass assignment can silently overwrite existing elements instead of creating new ones. Both are the same underlying pattern — an admin action trusting user-scoped input more than it should. Upgrade and audit recent bulk-duplicate operations for elements that changed instead of cloned.

Keycloak fails to fully validate encrypted SAML assertions, allowing unauthorized access

Keycloak's handling of encrypted SAML assertions has an improper-validation gap that lets an attacker gain unauthorized access — a second, unrelated Keycloak bug in today's batch (the FGAP realm-role escalation, already on today's watch) shows the identity-provider hardening work isn't fully done yet. If you run Keycloak with SAML-encrypted assertions enabled, patch past keycloak-services 26.6.4 and check IdP-side encryption configuration against the advisory.

jsonata's $toMillis function can be driven into resource exhaustion by malicious input

jsonata — the JSON query and transformation library embedded in countless Node.js pipelines and several low-code integration platforms — has a $toMillis function that can be handed input crafted to cause resource exhaustion, a straightforward DoS if you evaluate jsonata expressions against untrusted JSON. Upgrade to the patched release, and if you can't immediately, sandbox or rate-limit anywhere user-supplied data reaches a jsonata expression.

Anubis ransomware affiliates chain Citrix Bleed 2, BYOVD, and stolen credentials for initial access

Threat actors tied to the Anubis ransomware operation are exploiting Citrix Bleed 2 (CVE-2025-5777) for initial access, then leaning on legitimate RMM tooling and BYOVD drivers to move laterally, with credential theft as a recurring step in the chain. Not a package-registry attack, but the pattern — legitimate tooling abuse plus stolen credentials as the actual weapon — rhymes with everything else on this watch. If Citrix Bleed 2 patching stalled anywhere in your fleet, this is the reminder it's being actively chained by ransomware crews now, not just researchers.

12:00 ET · Forenoon Watch

mcp-memory-service's /api/documents/* routes ship with zero authentication — read, write, and delete any memory unauthenticated

Every route under /api/documents/* in mcp-memory-service is mounted without the Depends(require_read_access)/require_write_access guard that protects the equivalent /api/memories endpoints, so an unauthenticated attacker can upload documents into the memory store, read back any uploaded content, and wipe memories via remove-by-tags — all against a server that has MCP_API_KEY or OAuth configured and enabled. For an MCP memory backend this is both a data-integrity and a prompt-injection surface: an attacker can plant poisoned content an agent later retrieves as trusted context. Upgrade past 10.67.1, and if you're running the HTTP REST server for a team deployment, firewall /api/documents/* until you have.

Ghost frontend cache-poisoning XSS via x-ghost-preview header on any shared cache

An unauthenticated request carrying an x-ghost-preview header can alter Ghost's rendered frontend response, and behind a shared cache (Fastly, Cloudflare, nginx proxy_cache) that altered response gets stored and replayed to every subsequent visitor of the same URL — turning a single crafted request into stored XSS served to your whole audience. Affects Ghost 4.0.0 through 6.36.0. Patch immediately and purge/invalidate your CDN cache after upgrading, since a poisoned entry can outlive the patch if it's still sitting in cache.

Erlang/Elixir quic client never actually verified the server's TLS certificate — full MITM impersonation

The quic Hex package's client skipped CertificateVerify signature checking, chain validation, and hostname comparison entirely, so verify => true was a silent no-op and any on-path attacker could present an arbitrary certificate and impersonate any server; HTTP/3 traffic over the same client was equally exposed. Only PSK-resumed handshakes were unaffected, since those authenticate via the session binder instead of a certificate. Fixed in 1.4.4 — upgrade and confirm verify defaults to true in your config, since setting verify => false explicitly still opts back out.

Rancher + Fleet coordinated disclosure: cross-namespace secret leak (CVSS 9.9), YAML command injection (9.6), and project-to-host privilege escalation, plus four more Fleet bugs

Rancher and its Fleet GitOps component dropped seven advisories together: Fleet's Helm Deployer resolves valuesFrom references without validating namespace, letting a bundle in one namespace read secrets from any other (CVE, CVSS 9.9); Rancher has a command injection through an unsanitized YAML parameter (9.6) and a privilege-escalation path from Project Owner straight to host access (8.4); Rancher's GitHub App auth provider over-expands team membership (8.8); and Fleet separately has an unauthenticated webhook regex-injection, SSRF via unvalidated Helm repo URLs in fleet.yaml, and a Pod Security Standard bypass in the Fleet Agent. Anyone running Rancher-managed Kubernetes with Fleet GitOps has cluster-admin-adjacent blast radius here — patch to the fixed 2.14.2 / 2.13.6 / 2.12.10 (Rancher) and 0.15.2 / 0.14.6 / 0.13.11 / 0.12.15 (Fleet) lines and audit Fleet bundle definitions for cross-namespace valuesFrom references in the meantime.

OpenClaw coordinated disclosure: 13 advisories spanning scope-gate bypasses, a shell-allowlist escape, and forged trusted-proxy identity headers

OpenClaw — the agent gateway/bot-control-plane project — shipped a wide batch of authorization bugs at once: scoped chat.send requests routed through inherited external delivery can run with only operator.write where operator.admin should be required (CVSS 8.8); the POSIX safe-bin allowlist for system.run is widenable via shell expansion (7.1); QQBot's native approval buttons don't check the configured approver's identity (8.0); hook-triggered CLI runs can inherit the owner's MCP tool authority (8.4); and same-host trusted-proxy deployments can accept locally forged identity headers, alongside a marketplace metadata field that can point at unscanned extension payloads and an exec-approval UI that can truncate the command being approved so an operator approves something other than what they saw. The common thread is every trust boundary in an agent-control product — approval UI, scope inheritance, proxy trust — getting probed at once. Upgrade to 2026.6.5 or later (the fixes land across the 2026.5.12–2026.6.5 range depending on the advisory) and re-audit any automation that grants operator.write to routed or hook-triggered contexts.

oras-go disclosure cluster: tar hardlink path escape, credential-forwarding across redirects, and Bearer-token realm hijacking from a malicious registry

A malicious OCI registry can turn oras-go against its own caller in several ways at once: a tar hardlink entry with a relative Linkname escapes the extraction directory via process-CWD resolution (CVSS 7.1), blob uploads forward the caller's registry credentials across an unvalidated Location redirect (7.5), and a hijacked Bearer-token realm in the WWW-Authenticate challenge can exfiltrate credentials and refresh tokens outright; separately, file-store writes can escape workingDir via symlink traversal and registry credentials get forwarded across registry redirects. Anything that pulls artifacts with oras-go — including CI pipelines pulling Helm charts or OCI-packaged binaries — is exposed to a compromised or malicious upstream registry. Upgrade to oras-go v2.6.1+ (v1 users to the fixed 1.2.x line), and treat any registry your pipeline doesn't fully control as hostile input.

goshs WebDAV listener ignores --read-only/--upload-only/--no-delete flags entirely, plus a share-link download-limit race

goshs's WebDAV listener doesn't check any of the --read-only, --upload-only, or --no-delete mode flags (CVSS 8.1), so an operator who thinks they've locked a share down to read-only has actually left full WebDAV write/delete open the whole time. A separate bug lets a share-link's ?token=... be redeemed past its configured download limit via a redemption race. If you run goshs for ad hoc file sharing with those flags set, assume WebDAV has been wide open until you upgrade past 2.0.9.

Apify's Actor MCP server leaks your Apify API token to any malicious Actor via path-authority injection

@apify/actors-mcp-server builds Actor standby MCP URLs by string-concatenating a trusted base URL with an attacker-controlled webServerMcpPath pulled from the Actor's own definition, so a published Actor with a crafted path (e.g. @attacker.example/mcp) redirects the MCP client to a different host entirely — and the client attaches the victim's Authorization: Bearer <APIFY_TOKEN> to every outbound connection unconditionally. Any workflow that runs third-party Apify Actors through this MCP server is one malicious Actor away from token theft. Upgrade past 0.10.7 and rotate any Apify token that may have talked to an untrusted Actor.

Centrifugo's dynamic JWKS cache is keyed only by kid, letting a token for one tenant authenticate as another

When Centrifugo is configured with dynamic, templated JWKS URLs for multi-issuer/multi-tenant setups, its JWKS cache and singleflight lookup key on the JWT's kid header alone — not the resolved endpoint, issuer, or audience — so if tenant A and tenant B's JWKS documents happen to reuse the same kid, a token minted for tenant A verifies successfully as tenant B. Both connection-token and subscription-token verification share the vulnerable path. Affects all major versions (v2 through v6); upgrade, and if you can't yet, avoid templated JWKS URLs derived from iss/aud claims until you do.

Keycloak's Fine-Grained Admin Permissions let a limited client-management admin assign any realm role, including privileged ones

An admin scoped to client management only (via FGAPv2) can assign arbitrary realm roles — including highly privileged ones — to a client's scope mapping, and that injected role then projects straight into a user's token the next time they authenticate against the modified client. It's a privilege-escalation path that defeats the entire point of fine-grained admin permissions: a restricted admin becomes an unrestricted one. Upgrade past keycloak-services 26.6.4 and audit recent scope-mapping changes made by limited-scope admins for unexpected role grants.

OnGres SCRAM client silently downgrades channel-binding when the server's cert uses a modern signature algorithm

When a server presents a certificate signed with an algorithm outside the classic *WITH* naming scheme (Ed25519, post-quantum algorithms), scram-client's channel-binding-data derivation throws internally, swallows the exception, and returns an empty byte array — which the client then misreads as "the environment has no channel binding available" and silently falls back from SCRAM-SHA-256-PLUS to plain SCRAM-SHA-256. An attacker positioned for TLS MITM can exploit exactly this fallback to bypass the channel-binding protection the -PLUS variant exists to provide. Upgrade scram-client/scram-common past 3.2, and if your Postgres or other SCRAM-backed server presents an Ed25519 or PQC cert, verify channel binding is actually being negotiated post-patch.

SurrealDB permissions cluster: 11 advisories covering LIVE-query and field/edge-level SELECT permission bypasses, plus a pre-auth memory-amplification DoS

SurrealDB shipped 11 medium-severity advisories in one batch, almost all the same shape: field- and edge-level PERMISSIONS checks getting bypassed through some alternate access path — indexed COUNT fast paths, JSON Patch copy/move with an empty from, error-message side channels, LIVE query subscriptions that survive session changes, RELATE overwriting edges without UPDATE permission, and USE NS/DB implicit creation skipping DEFINE authorization checks. A separate, unrelated bug lets an unauthenticated /sql WebSocket connection amplify memory usage via unbounded frames. None of these are remote pre-auth code execution, but if you rely on SurrealDB's row/field permission system as a real multi-tenant boundary, most of the boundary just turned out to be soft. Upgrade to 3.1.0 and re-test that permission-gated fields and edges actually stay hidden across LIVE subscriptions and JSON Patch operations.

GoFiber: X-Real-IP spoofing via Header.Add() in BalancerForward, plus a BasicAuth timing oracle for username enumeration

Fiber's BalancerForward appends rather than replaces X-Real-IP via Header.Add(), so a client-supplied X-Real-IP header can ride along next to the proxy-set one and confuse downstream IP-based access control or rate limiting depending on which value a consumer reads first; separately, the default BasicAuth authorizer's comparison timing leaks whether a username exists at all. Neither is a takeover on its own, but IP-trust logic and credential enumeration are both building blocks for a bigger attack chain. Upgrade fiber/v2 past 2.52.13 or v3 past 3.2.0.

VEIL#DROP: Blogger-hosted pages used as a multi-stage dropper for the PureLogs infostealer

Securonix is tracking a campaign (VEIL#DROP) that uses spear-phishing or drive-by compromise to land victims on Blogger-hosted pages that serve as a multi-stage loader for PureLogs, an infostealer. Not a package-registry attack, but it's the same social-engineering-to-credential-theft shape this watch tracks elsewhere, this time abusing a trusted blogging platform as infrastructure instead of npm or PyPI. Treat unexpected Blogger links in outreach or recruiting messages the same way you'd treat an unsolicited npm package: run it nowhere near a machine with real credentials.

06:00 ET · Morning Watch

Mailpit's DoS fix only covered one endpoint — four sibling APIs are still unbounded and unauthenticated by default

May's fix for Mailpit's /api/v1/send memory-exhaustion DoS (GHSA-fpxj) wrapped only that endpoint in a body-size cap; four sibling JSON handlers — SetReadStatus, DeleteMessages, SetMessageTags, ReleaseMessage — still decode unbounded request bodies and stay reachable unauthenticated in the default `docker run axllent/mailpit` deploy. A single 16MB request with a multi-million-element IDs array drives RSS from ~8MB to ~450MB, and memory isn't freed between requests, so repeated connections compound it into a full OOM on whatever CI or dev host is running the mail-catcher. Upgrade past 1.30.0, or put a request-size limit in front of Mailpit's API port until you can.

hey-api/openapi-ts's generated SDK template lets a crafted $query___proto__ key overwrite an object's prototype chain

The params-building helper that @hey-api/openapi-ts copies verbatim into every generated SDK strips recognized slot prefixes like `$query_` from unknown keys without validating what's left, so a request field literally named `$query___proto__` overwrites the returned params object's prototype with attacker-controlled data. Any proxy, BFF, or gateway that forwards user-supplied parameters into a hey-api-generated client method is exposed, and the same template ships downstream in packages like @opencode-ai/sdk and @trigger.dev/sdk. Upgrade to 0.97.3+ and regenerate any client built against an older version — the template fix doesn't retroactively patch code already generated.