v vanemmerik.ai / SUPPLY-CHAIN
Supply Chain · Watch Friday · 19 June 2026 End-of-day synthesis 4 watches · 40 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 — The agentic toolchain audited itself in public all day — Langflow and Network-AI criticals, an MCP-server SSRF/XSS cluster, and cross-tenant breaks across the agent-memory stores — and kept going after dark with a LangSmith SDK file-read and a Lokka MCP Azure-token leak.

Today's advisories clustered around one surface almost entirely: the tools engineers are bolting onto LLMs. The morning opened with OpenClaw's coordinated disclosure and a run of untrusted-model-file parser bugs; by First Watch the agent and MCP beat had taken over the page.

Langflow shipped two criticals — an `/api/v1/responses` IDOR that runs another user's flow (9.9) and a `BaseFileComponent` arbitrary file read that chains to RCE (9.6) — and Network-AI added a third tranche of file-metadata-trust and unauthenticated-listener bugs on top of this morning's empty-secret and shell-allowlist criticals. MCP servers leaked in every direction: SearXNG MCP DNS-rebinding SSRF, appium-mcp and Uni-CLI transport and XSS, dbt MCP token disclosure. And the agent-memory stores failed tenant isolation wholesale — stigmem-node ran its decay, quarantine, and RTBF paths tenant-blind, EverOS wrote outside its memory directory, and OpenRemote let any realm bulk-delete another's alarms.

Late escalation at 21:00 ET: the agentic thread didn't quiet down after the 18:00 synthesis. The LangSmith SDK's `TracingMiddleware` can be coerced into reading a local file and shipping it to LangSmith as a trace attachment (7.7); Lokka, an Azure MCP server, concatenated user input into ARM URLs and could leak Azure bearer tokens to an attacker host; and SurrealDB landed a six-advisory batch headlined by a role-gated arbitrary file read (7.7). The observability and cloud-credential layers are now part of the same story — paths, URLs, and trace inputs all treated as configuration.

The bright spot is the boring plumbing underneath it. undici, http4k, and parse-server all landed coordinated multi-advisory fixes for their proxy, crypto, auth, and DoS gaps — the mature HTTP layer is patching cleanly and on a cadence even as the agent layer churns above it.

→ Operational priority for the night if Langflow or Network-AI is reachable on anything routable, pull it behind authentication and upgrade before you sleep — both carry authenticated-attacker criticals in the 9.6–9.9 range — then bump `langsmith` to 0.8.18, Lokka to 2.1.2, and SurrealDB to 3.1.5, and treat every MCP server and desktop-app loopback binding as reachable from any web page the operator has open.

21:00 ET · Last Watch

LangSmith SDK: TracingMiddleware coerced into arbitrary server-side file read (7.7)

An attacker who can reach a server running the LangSmith SDK's `TracingMiddleware` can make it read an arbitrary local file and upload the contents to LangSmith as a trace attachment. LangSmith sits squarely in today's agentic-toolchain thread — the observability layer becomes the exfiltration path. Upgrade `langsmith` to 0.8.18.

Lokka (Azure MCP server): ARM URL path concatenation leaks bearer tokens to attacker host

Lokka built Azure Resource Manager request URLs by string-concatenating user-controlled path input, so a crafted path could alter the URL authority and ship Azure ARM bearer tokens to an unintended host. Same MCP-token-leak shape as today's dbt MCP and Uni-CLI transport bugs, now with cloud credentials attached. Upgrade `@merill/lokka` to 2.1.2.

SurrealDB: arbitrary file read via DEFINE ANALYZER mapper() filter (7.7)

A SurrealDB `EDITOR`/`OWNER` role can point a `DEFINE ANALYZER ... FILTERS mapper('<path>')` filter at any file the server process can read and recover its contents through full-text search. Arbitrary file read gated on a database role, not network position. Upgrade to 3.1.5.

Anki: local HTTP server missing Origin validation + path traversal lets any open page read files

Anki's bundled localhost media server fails to validate the `Origin` header and several endpoints allow path traversal, so any web page the user has open can read local files through the desktop app's own listener. Same loopback-binding-is-reachable shape as today's MCP servers — a native desktop app this time. Upgrade `aqt` past 25.9.2.

githubtoplanguages: command injection via issue title in Discord-notify workflow

A GitHub Actions workflow interpolates `github.event.issue.title` directly into a Bash variable assignment, so an issue title containing command-substitution syntax runs on the runner. Classic untrusted-event-field-into-shell injection. Pin `gouef/githubtoplanguages` to 1.1.4 and quote/sanitize any `github.event` field used in `run:` steps.

SurrealDB: authenticated DoS via deep operator chains (6.5)

A single query with a long flat operator chain (`RETURN 1 + 1 + 1 + ...` with tens of thousands of terms) parses into a one-level-deep expression tree and crashes the server. Authenticated DoS; upgrade to 3.1.5.

python-zeep: SSRF via transitive WSDL/XSD references (5.9)

python-zeep follows transitive `xsd:import`/`include` and lxml entity references and fetches their http/https URLs, and `Settings.forbid_external` doesn't fully disable it — SSRF via a malicious WSDL/XSD. Upgrade to 4.3.3.

ChatterBot: symlink-following arbitrary write via UbuntuCorpusTrainer (5.5)

`UbuntuCorpusTrainer.extract()` uses a predictable home-rooted path with a check-then-create pattern followed by `tar.extractall`, so a pre-planted symlink yields arbitrary write. Local-only; same symlink-following shape as today's Network-AI and pydantic-settings items. Patch when a fixed release ships (affects <= 1.2.13).

SurrealDB: SSRF via JWKS URL redirect following in JWT key fetch (4.1)

SurrealDB fetches JWKS documents with a `reqwest` client that follows redirects, and the network-capability check validates only the original URL, not the redirect target — SSRF via a redirecting JWKS host. Part of the SurrealDB 3.1.5 batch.

18:00 ET · First Watch

Langflow: two criticals — /api/v1/responses IDOR runs another user's flow, BaseFileComponent arbitrary file read chains to RCE

Langflow lands two criticals at once. An IDOR in `/api/v1/responses` (`get_flow_by_id_or_endpoint_name`) lets any authenticated user execute another user's flow by passing the victim's flow ID (CVSS 9.9), and every `BaseFileComponent`-derived node — Read File, Docling, Unstructured, the NVIDIA and video ingesters — takes a user-controlled path and reads arbitrary local files in a chain that reaches RCE (CVSS 9.6). The same batch adds an unauthenticated multipart-boundary upload DoS and a logout that never clears the session. If Langflow is reachable by more than one tenant or exposed at all, upgrade now and pull it behind auth — multi-user isolation and file handling are both broken.

OpenRemote Manager: removeAlarms cross-realm IDOR lets any realm bulk-delete another tenant's alarms

OpenRemote Manager's bulk `removeAlarms()` checks only that the caller's own realm is active, never that the supplied alarm IDs belong to that realm, so an authenticated user in any realm can bulk-delete alarms across every other tenant (CVSS 9.6). This is the same cross-tenant IDOR shape running through today's agent-memory advisories — the object ID is attacker-controlled and the authorization check is scoped to the caller, not the target. Upgrade; if you run OpenRemote multi-tenant, treat the alarm store as currently destroyable by any account.

MCP-server cluster: SearXNG MCP DNS-rebinding SSRF + unbounded read, appium-mcp XSS, Uni-CLI browser-origin transport, dbt MCP token leak

A cluster of MCP-server advisories disclosed together. SearXNG MCP's `web_url_read` validates the hostname string but never resolves DNS, so an attacker domain pointing at a private IP defeats the SSRF blocklist (CVSS 7.1), and the same tool enforces its 5 MiB cap only via a `Content-Length` HEAD, so a response that omits the header loads unbounded into memory (CVSS 7.5). Alongside them: `appium-mcp` interpolates attacker-controlled element attributes into an MCP-UI HTML template (XSS, 8.2), Uni-CLI's legacy HTTP MCP transport accepted browser-origin localhost POSTs without an Origin check, and the dbt MCP server's OAuth context endpoint leaks dbt Platform tokens unauthenticated. Patch each; treat every MCP server's loopback binding as reachable from any web page the operator has open.

stigmem-node: agent-memory store fails tenant isolation across decay, quarantine, and RTBF paths (cross-tenant BOLA trio)

Three advisories show the stigmem-node agent-memory store leaking across tenants in every lifecycle path. The decay sweep's candidate queries carried no `tenant_id` predicate, so a `write` credential for one tenant expires and counts facts for all of them; the quarantine review surface lets a tenant admin list, read, and admit/reject other tenants' quarantined facts; and RTBF tombstones default to the `"default"` tenant and suppress reads tenant-blind. Every one is a missing `tenant_id` filter on a query — the same isolation gap as today's OpenRemote and Langflow IDORs. Upgrade and audit any per-tenant query in your own memory layer for the same omission.

Network-AI: third tranche — poisoned backup manifest → arbitrary recursive delete, plus restore/backup path traversal and an unauthenticated ApprovalInbox

On top of this morning's two `network-ai` criticals (empty-default-secret unauth path, allowlist→/bin/sh RCE), a third batch lands. `pruneBackups()` trusts the `path` field inside an attacker-placeable `_manifest.json` and passes it straight to `rmSync(..., {recursive:true, force:true})`, turning a poisoned backup into arbitrary recursive deletion (CVSS 7.1); the restore and backup paths add backup-ID path traversal and symlink-following copies; and the `ApprovalInbox` HTTP server has no authentication, so anyone can approve pending actions. The throughline is consistent across the whole disclosure: network-ai trusts file metadata and local HTTP surfaces it shouldn't. Pin the patched release and keep every network-ai listener off routable interfaces.

VCR.py: cassette YAML loaded with PyYAML's unsafe loader — a !!python/object tag is RCE on use_cassette()

VCR.py deserializes recorded cassette files with PyYAML's object-constructing loader instead of the safe loader, so a cassette carrying a `!!python/object/apply:` tag executes arbitrary Python the moment `VCR().use_cassette()` loads it — before any HTTP interaction replays (CVSS 7.8). Cassettes are test fixtures that move through repos, PRs, and shared fixture bundles, which makes this a clean supply-chain pivot into CI. Upgrade VCR.py and treat any cassette you didn't record yourself as untrusted code, not test data.

symfony/ux-toolkit: ux:install recipe manifest path traversal writes attacker files anywhere on the developer's machine

The `ux:install` command copies files listed in a recipe kit's `copy-files` map, guarded only by `Path::isRelative()` — which returns true for `../../../etc`, and `Path::join()` then resolves the `..` segments out of the intended directory (CVSS 7.8). A crafted or compromised kit therefore writes and reads arbitrary paths on the developer's machine at install time. Same install-time-trust shape as the agentic-tooling RCEs all day, just aimed at the dev box; upgrade ux-toolkit and only run `ux:install` against kits you trust.

EverOS: unvalidated sender_id in /api/v1/memory/add is a path traversal write into the memory store

EverOS (≤1.0.0) validates `app_id`/`project_id` as path-safe but not the per-message `sender_id`, which becomes the `owner_id` joined into the filesystem path where an extracted memory episode is written as Markdown — a `sender_id` with `../` directs the write outside the configured memory directory (CVSS 8.2). Another agent-memory store treating a request field as a trusted path component, the same week stigmem-node failed tenant isolation. Upgrade and validate every identifier that reaches a filesystem join.

Untrusted-parser DoS cluster: Ultimate Sitemap Parser billion-laughs + gzip bomb, MessagePack OOB crash, py7zr zip bomb + O(n²)

A run of parser-resource-exhaustion bugs against untrusted input. Ultimate Sitemap Parser feeds attacker XML to expat with DTDs enabled (billion-laughs, CVSS 7.5) and caps sitemap size only on compressed bytes, so a 549 KB gzip expands past 120 MiB (CVSS 7.5). MessagePack for Python SEGVs if an Unpacker is reused after a caught error on untrusted input. py7zr adds an unchecked-extraction zip bomb and an O(n²) `PackInfo._read()`. None are RCE, but each is a trivially-triggered DoS in a library that parses content fetched from elsewhere — cap input sizes and rebuild the Unpacker per stream.

http4k: coordinated crypto/auth batch — HmacSha256.hash was an unkeyed digest, DigestAuth defaulted always-true, reverseProxy Host matched on substring

http4k shipped a multi-advisory hardening batch. `HmacSha256.hash(payload)` computed a plain unkeyed SHA-256 despite the `Hmac` name (no key parameter), now deprecated in favour of `Sha256.hash`/`Sha256.hmac`; `ServerFilters.DigestAuth`/`DigestAuthProvider` defaulted to an always-true credential check; `reverseProxy()` defaulted to substring (`Contains`) Host matching, so `evil-example.com` matches an `example.com` rule; and `BasicCookieStorage` (now `InsecureCookieStorage`) ignored RFC 6265 attributes. Bump http4k and grep for `HmacSha256.hash` and bare `reverseProxy()`/`DigestAuth` defaults in your filters.

Defensive-infra batch: OpenBao Transit crash + namespace/lease scoping gaps, Traefik NGINX provider fails open on auth-secret lookup

A cluster of lower-severity infra fixes worth tracking. OpenBao's Transit engine crashes on `derived:true` asymmetric key creation and had several namespace/lease cross-scope gaps (system-backend namespace management, cross-namespace lease revoke/renew, wrong LDAP escape function). Separately, Traefik's Kubernetes Ingress NGINX provider fails open — routes stay served — when auth-secret resolution fails, so a missing or unreadable secret silently removes authentication rather than blocking the route. Patch on your normal cadence, but prioritise the Traefik fail-open if you gate ingress auth through annotations.

12:00 ET · Forenoon Watch

Network-AI: two criticals — incomplete CVE-2026-46701 fix leaves empty-default-secret unauth path, plus allowlist→/bin/sh RCE

Two critical advisories land on the npm `network-ai` MCP server at once. The 5.4.5 fix for CVE-2026-46701 only closed the CORS half: the SSE MCP server still defaults to an empty secret, so unauthenticated cross-origin tool invocation survives (CVSS 9.1). Worse, the sandbox allowlist (`SandboxPolicy.isCommandAllowed`) glob-matches the whole command string but `ShellExecutor` runs it through `/bin/sh -c`, so a scoped allow like `git *` also matches `git status; <anything>` — matching and execution disagree on what a command is, and a compromised agent gets arbitrary execution (CVSS 9.9). Pull network-ai off any routable interface and treat its allowlist as non-defensive until the empty-default-secret and shell-parsing fixes ship.

Tilt: HUD server is unauthenticated — trigger Tiltfile resources, read the session token, plus pprof + cross-site WebSocket hijack

The Tilt dev-environment HUD HTTP server registers its handlers on a `gorilla/mux` router with no authenticating middleware, so when the HUD is bound to a non-loopback address a network attacker can trigger pre-defined Tiltfile resources, tamper with Tiltfile args, and read full engine state including the `Tilt-Token` session token — then reach the apiserver through a token-attaching proxy. The same disclosure carries unauthenticated `pprof` debug endpoints and cross-site WebSocket hijacking of the HUD stream. Keep the Tilt HUD on loopback only; if you ever set a non-loopback host for remote dev, you have shipped an unauthenticated control plane.

DotVVM: AuthorizeActionFilter is a silent no-op — every protected action is unauthenticated (plus routing ReDoS, unrestricted upload)

DotVVM's `AuthorizeActionFilter` "simply does nothing" — no bypass technique required, any action relying on it for authorization has been wide open. The same batch adds a ReDoS in DotVVM routing and an unrestricted file upload. Upgrade to 4.3.15 / 4.2.11 / 5.0.0-preview09, or swap to `AuthorizeAttribute` (same interfaces, correctly implemented) as an immediate workaround, and audit any action you believed `AuthorizeActionFilter` was protecting.

AWS Bedrock AgentCore Python SDK: install_packages() arg-delimiter injection → command exec in the Code Interpreter sandbox

The `bedrock-agentcore` SDK's `install_packages()` builds a `pip install` shell command in the Code Interpreter client, and crafted package-name arguments bypass input validation to inject extra arguments and execute arbitrary commands in the Code Interpreter sandbox (CVSS 7.3, remote authenticated). Same argument-delimiter-injection shape as the agentic-tooling RCEs landing all day — the package name is untrusted input, not a label. Upgrade the SDK and never pass agent- or user-derived strings straight into `install_packages()`.

AI-agent RCE cluster: agentic-flow execSync injection, agent-coderag runs repo gradlew, ouroboros-ai .env denylist still incomplete

Three more agent-framework RCEs in the same beat as this morning's OpenClaw run. `agentic-flow` (<=2.0.13) interpolates MCP tool parameters straight into `execSync()` — a partial-fix gap the earlier CWE-78 commit missed in the MCP server files (CVSS 8.8). `agent-coderag` unconditionally executes a repository-controlled `gradlew` during its default `sync` dependency-discovery flow, so indexing a malicious Gradle repo is arbitrary code execution with no flags or auth (CVSS 8.6). And `ouroboros-ai`'s CVE-2026-47211 fix left its `_UNTRUSTED_ENV_DENYLIST` incomplete — `CODEX_HOME`/`OPENCODE_CONFIG`/`XDG_CONFIG_HOME` and other execution-routing keys still let an auto-loaded project `.env` reach RCE, the exact rhyme of the OpenClaw/`.env`-as-untrusted-input pattern. The throughline holds: for an AI coding agent, the repository you open is attacker-controlled input — pin patched versions and treat opened-workspace `.env` files as data.

CedarJava: type confusion + policy injection across the Java↔Rust FFI authorization boundary

Two flaws in `com.cedarpolicy:cedar-java`, the Java binding many teams use for fine-grained authz. Record-to-entity type confusion across the Java-Rust FFI lets attacker JSON impersonate the reserved `__entity`/`__extn` magic shapes, corrupting authorization input; separately, `toCedarExpr()` fails to escape `"` or `\`, so any integrator building policy text at runtime from user-controlled values has a Cedar-expression injection (both CVSS 8.8). If you construct Cedar requests or policies from untrusted input, upgrade and stop using `toCedarExpr()` for runtime policy assembly — a bypass here is an authorization bypass everywhere it gates.

undici batch: SOCKS5 proxy pool reuse routes requests cross-origin; WebSocket fragment-count DoS; Set-Cookie header injection

A multi-advisory undici batch, led by a high: `Socks5ProxyAgent` reuses one connection pool across origins without checking the pool's origin matches the request, so credentials and data meant for origin B get dispatched to origin A, wrong-origin responses are trusted, and HTTPS can silently downgrade to HTTP (CVSS 7.5). The batch also includes a WebSocket-client DoS — `maxPayloadSize` caps cumulative bytes but not fragment count, so many empty continuation frames grow memory unbounded (CVSS 7.5) — plus Set-Cookie header injection via percent-decoding, SameSite downgrade, and keep-alive response-queue poisoning. Bump undici (direct and transitive — it's under most Node HTTP stacks); prioritise the SOCKS5 fix if you proxy outbound traffic.

parse-server: ~1 KB deeply-nested query operators block the event loop with exponential-time processing

A single small (~1 KB) Parse Server query containing deeply nested condition operators is processed in exponential time, blocking the Node.js event loop and making the server unresponsive to every client for the duration. Unauthenticated, trivially repeatable — classic algorithmic-complexity DoS against a query parser. Patch parse-server; if you can't immediately, cap query nesting depth at the gateway.

tract-onnx: ONNX external_data `location` path traversal reads arbitrary local files on model load

`tract` (the `tract-onnx` crate) joins an ONNX tensor's external-data `location` onto the model directory with no sanitization, so a crafted `.onnx` file makes tract open and read an arbitrary local file at load time, its contents flowing into model tensors (CVSS 6.1). This is the same untrusted-model-file shape as this morning's tract-nnef OOB read and yesterday's vLLM GGUF leak — the model is the attack surface. Upgrade tract and treat user-supplied ONNX weights as untrusted input parsed in isolation.

JupyterLab: Extension Manager renders unsanitized PyPI `project.urls` — javascript: home-page link is stored XSS

A malicious PyPI package can put a `javascript:` URL in its `[project.urls]` metadata, and JupyterLab's Extension Manager renders it as the extension's home-page link without validating the protocol — clicking the extension name runs attacker JavaScript in the JupyterLab origin. Stored XSS sourced from package metadata is a neat supply-chain pivot into a notebook server. Patch JupyterLab; until then, don't click home-page links in the extension manager for untrusted packages.

06:00 ET · Morning Watch

OpenClaw: ~14 more advisories — workspace .env/PATH steer the runtime, allowFrom trusts mutable names

OpenClaw's coordinated-disclosure run continues with roughly fourteen more advisories: workspace-`.env`-derived `npm_execpath`, `STATE_DIRECTORY` and service `PATH` that can redirect the bundled runtime's dependency install or the `trash`/maintenance command it selects, plus `allowFrom` bindings that trust mutable Discord/Zalo display names and several command-scope and session-visibility gaps. Every advisory is explicitly scoped to OpenClaw's trusted-operator model — the realistic exploit is a poisoned repository whose `.env` an authenticated operator opens, not a network attacker. Pin OpenClaw to the patched release and treat any opened workspace's `.env` as untrusted input rather than configuration.

Kirby: access-control + XSS batch — /api/site/find leaks page content past pages.access

A Kirby CMS batch lands, led by a broken-access-control bug where `/api/site/find` returns full page content and metadata without checking the `pages.access` permission — any site that disables `pages.access` for a role leaks arbitrary pages to that role. The same batch carries a `Dom::sanitize()` XSS from incomplete HTML/XML sanitization, a writer-field self-XSS, top-level-draft file exposure, and request-header injection in `Http\Remote`. Upgrade to the patched Kirby release; prioritise the `site/find` fix if you run role-based page restrictions.

OpenTelemetry Collector: githubreceiver silently ignores required_headers auth

The OpenTelemetry Collector's `githubreceiver` validates `required_headers` at startup but never enforces them on incoming webhook requests, so the configured auth is silently a no-op — the same bug class as the earlier `awsfirehosereceiver` bypass (GHSA-prf6-xjxh-p698). Any collector exposing the GitHub webhook receiver on a routable interface and leaning on `required_headers` for auth is effectively unauthenticated. Patch contrib and, until then, front the receiver with a proxy that actually checks the header.

tract-nnef: integer overflow in NNEF .dat tensor parser yields OOB read on model load

An integer overflow in tract-nnef's `read_tensor` (`.dat` tensor parser) returns a memory-unsafe tensor and triggers an out-of-bounds read when loading a crafted NNEF model archive through the public `model_for_path`/`model_for_read` API. Same shape as yesterday's vLLM GGUF leak — the model file is the untrusted input, so any service loading user-supplied NNEF weights is exposed. Upgrade to 0.21.16 / 0.22.2 / 0.23.1.