v vanemmerik.ai / SUPPLY-CHAIN
Supply Chain · Watch Thursday · 28 May 2026 End-of-day synthesis 4 watches · 31 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 Sicoob banking-SDK impersonator on NuGet exfiltrates client certs through Sentry, the Symfony tranche tops twenty advisories, and a late-evening paired Dulwich disclosure revives the NTFS-hostile-tree-entry class on Windows.

The morning was quiet on the active-attack side, but the disclosure pipeline opened wide after lunch. Socket caught a Brazilian banking-cooperative impersonator on NuGet exfiltrating client IDs, PFX passwords, and signed banking certificates through Sentry telemetry — using a vendor SDK as the lure and Sentry-as-covert-C2 is the same pattern we saw earlier this month in the npm tranche, now rotated to a financial target and a different registry.

Symfony's hardening pass crossed the twenty-advisory line — six more landed today, the worst of them three webhook parsers (Mailtrap, Mailjet, LOX24 SMS) that take a signing secret but never read it, so any unauthenticated POST forges delivery events. compliance-trestle, which we flagged yesterday with a no-patch path-traversal-to-RCE, escalated overnight: a Server-Side Template Injection in `trestle author jinja` makes attacker-controlled data fields executable through Jinja recursion, and three companion advisories — arbitrary file write, arbitrary file read, and SSRF — landed alongside it with patches now available. Yesterday's no-patch is today's patch-tonight. FortiClient EMS remains under active exploitation per Arctic Wolf, dropping a credential stealer named EKZ to managed endpoints — the same endpoint-management-pushes-malware shape as yesterday's Nx Console KEV add. The bright spot is OpenBao publishing a coordinated batch — cross-namespace lease revocation bypass alongside two information-leak mediums in one release. Coordinated disclosure across an entire feature area is the discipline we want to see more of, and it's a notable contrast with the months-long Pimcore drip.

Late escalation at 21:00 ET: GHSA published a paired Dulwich tranche — a `%P` merge-driver command injection via `subprocess.run(..., shell=True)` and an arbitrary file write via NTFS-hostile tree entries (`\`, `:`, `git~N` aliases all accepted by the path-element validator, plus core.protectNTFS silently ignored because of a wrong option name) — both of which reach RCE on Windows the moment a victim clones, fetches, or merges an untrusted repo. The NTFS variant is the same class as upstream Git's 2019 CVE-2019-1353 and lands on every Python tool that wraps Dulwich (dulwich, jelly-fish, pip-tools alternatives). Arcane joined them with an authenticated `include:` directive in a compose file that reads any file the backend can — the project SQLite (`arcane.db`) contains every user's bcrypt hash and API key, so first-hop authenticated turns into platform-admin and host RCE via Docker control plane. The shape is the same ordering bug we keep seeing: `CreateProject` writes the compose content without validation while `UpdateProject` runs the include-path validator. python-tuf rounds out the late batch with a medium that's interesting more than urgent — `fnmatch.fnmatch` calls `os.path.normcase`, so on Windows the TUF spec's case-sensitive delegation path matching silently becomes case-insensitive, breaking the authorization decision for any python-tuf client (including PyPI's update tooling) depending on which OS the client runs on.

→ Operational priority for the night if any Windows endpoint, CI runner, or developer laptop runs a Python tool that bundles Dulwich (check `pip show dulwich` and your dependency-resolver caches), assume cloning an untrusted repo is a write-to-`.git\hooks` primitive and disallow it until you've upgraded; also scan NuGet manifests and lock files for any Sicoob-impersonating package and apply the compliance-trestle update if any part of your compliance pipeline fetches third-party OSCAL profiles.

21:00 ET · Last Watch

Dulwich paired RCEs: %P merge-driver shell=True command injection, NTFS-hostile tree entries plant `.git\hooks\pre-commit.exe` on Windows clone/fetch

Dulwich is the pure-Python Git implementation that backs pip-tools alternatives, Mercurial bridges, and a long tail of CI/CD and forge tooling. The merge-driver bug: `ProcessMergeDriver` substitutes the tree-controlled file path into the configured merge driver command via the `%P` placeholder and runs it with `subprocess.run(cmd, shell=True)` — any victim with a `%P`-using merge driver configured who merges an attacker-controlled branch hits arbitrary command execution. The NTFS bug is the more dangerous of the pair: the path-element validator accepts `\`, `:`, and `git~N` short-name aliases, so a single tree entry named `.git\hooks\pre-commit.exe` materializes as a nested file inside the victim's `.git` directory on Windows — Git for Windows then executes that hook on the next `git commit`. core.protectNTFS and core.protectHFS were also silently ignored because the option name was misspelled, and protectNTFS only defaulted to true on Windows even though upstream Git has defaulted it to true everywhere since CVE-2019-1353. Same class as CVE-2019-1353; treat any Windows endpoint or CI runner that clones, fetches, or checks out untrusted repos with Dulwich as already compromised and upgrade before the next `git commit` runs.

Arcane Docker UI: authenticated `include:` directive in compose file reads any host file — arcane.db exposes every bcrypt hash and API key

Arcane is a self-hoster Docker management UI. `ProjectService.CreateProject` writes attacker-supplied compose content to disk without running the include-path validator that `UpdateProject` runs, and `GetProjectFileContent` returns the contents of any Docker Compose include directive before path-traversal validation — so any authenticated user can declare `include: ['../../../../etc/passwd']` and read arbitrary files the Arcane backend can. The crown-jewel target is `/app/data/arcane.db`, the SQLite database that holds every user's bcrypt hash and API key; from there the path is offline crack → admin → host RCE via the Docker control plane. Auth boundary is low (it's a Docker UI), and the bug shape — validate-on-update-not-on-create — is the same recurring ordering issue worth grepping for in any backend you maintain. Patch immediately; until you do, rotate every Arcane password and API key as if the DB has already been exfiltrated.

python-tuf: delegation path matching is platform-dependent — Windows clients lower-case path patterns via ntpath.normcase, breaking the TUF spec

`DelegatedRole._is_target_in_pathpattern` decides whether a given target path is authorized by a delegation's glob pattern using `fnmatch.fnmatch`, which calls `os.path.normcase` on both arguments before matching. On POSIX `normcase` is the identity; on Windows it lowercases the input and replaces `/` with `\`. The result is that python-tuf's authorization decision for a target is case-sensitive on Linux/macOS but case-insensitive on Windows — a TUF specification violation in the `ngclient` implementation. Real-world impact depends on the delegation tree: any repository whose security model assumes case-sensitive path discrimination (`Critical/*.deb` vs `critical/*.deb`) silently breaks for Windows clients. Worth a heads-up rather than a patch-tonight, but every Python supply-chain tool that uses python-tuf to enforce delegated signing — including PyPI's update tooling — inherits the asymmetry. Upgrade when the maintainers cut a release.

18:00 ET · First Watch

Malicious NuGet package impersonates Sicoob banking SDK — exfiltrates client IDs, PFX passwords, and certificates through Sentry telemetry

Brazilian financial cooperative Sicoob has a widely-used .NET SDK; the malicious NuGet package mimics it closely enough that a quick package-name search would not flag it. On install or first call it harvests the client ID, PFX certificate password, and the certificate bytes themselves from disk and POSTs them to a Sentry DSN the attacker controls — exfiltration over a real Sentry endpoint blends with normal observability traffic and bypasses most outbound allowlists. Sentry-as-covert-C2 is the same pattern Socket flagged in the npm tranche earlier this month; rotating to NuGet and a banking target is the new wrinkle. Scan your .NET solution manifests and lock files for any Sicoob-name-similar package immediately; if you find one, treat every PFX it could have read as compromised and rotate the cert with the issuing CA.

FortiClient EMS auth-bypass (CVE-2026-35616) under active exploitation — credential stealer 'EKZ' pushed to managed endpoints

Arctic Wolf is tracking an active campaign exploiting the recently-patched FortiClient EMS authentication bypass (CVE-2026-35616) to push a previously-undocumented credential stealer named EKZ to endpoints managed by the EMS. The TTP — abuse legitimate endpoint-management infrastructure to deliver malware to the endpoints it manages — is the same shape as yesterday's Nx Console KEV add. If your EMS is unpatched and internet-reachable, assume compromise and rotate credentials for every account that has logged in through any managed endpoint since the patch landed. Patch the EMS, audit the deployed-package list it pushed in the last 30 days for anything signed by an unexpected publisher.

compliance-trestle continuation: SSTI RCE via Jinja recursion, jinja --output path traversal, profile-import arbitrary file read, SSRF in remote fetcher

Yesterday we flagged compliance-trestle's path-traversal-to-RCE as no-patch-available; today IBM published four coordinated advisories with fixes. The headline is the `trestle author jinja` SSTI — because the renderer recursively re-compiles rendered output, attacker-controlled data fields (SSP titles, lookup-table values) become executable through Jinja even though the template author only intended to print plain text. The `-o/--output` flag accepts `../` and absolute paths, so an attacker who can drive `trestle author jinja` can drop into `.github/workflows/*.yml` or `.git/hooks/*` for CI/CD or local code execution. Profile-import resolves `trestle://../../etc/passwd`-style URIs without boundary-check (arbitrary read), and the HTTPS fetcher passes user-supplied URLs straight to `requests.get` (SSRF, including to `169.254.169.254`). Upgrade now; the no-patch window we documented yesterday is closed.

OpenBao coordinated triple: cross-namespace lease revocation ACL bypass, Kerberos auth token accumulation, inline-auth audit-log header redaction

OpenBao (the HashiCorp Vault community fork) shipped three advisories in one release. The high is cross-namespace lease revocation: the legacy undocumented `sys/revoke` and `sys/renew` endpoints don't enforce namespace ACL, so a tenant in namespace A who learns a lease ID in namespace B can revoke or renew B's credentials — multi-tenant separation breaks for anyone using the legacy revoke path. The two mediums are quieter: the Kerberos auth `GET` handler creates ghost tokens that storage accumulates but no one can use, and inline-auth incorrectly redacts non-auth headers while keeping auth-related ones in cleartext (audit-log review needed if your audit device is anywhere an attacker could have read). Upgrade to v2.5.4 in the next maintenance window. Notable as a counterexample to the recent multi-advisory drip pattern (Pimcore, Symfony) — OpenBao coordinated and published the full batch together.

Automad CMS: unauthenticated POST to setup endpoint returns every admin's bcrypt hash and TOTP secret

Automad leaves `/_api/user-collection/create-first-user` reachable after initial setup is complete, and the endpoint returns the full serialized user collection in its JSON response — bcrypt hashes for every admin in `>= 2.0.0-alpha.1, <= 2.0.0-beta.27`, plus TOTP secrets in `2.0.0-beta.27`. Any Automad install reachable over HTTP yields its credential database to a single unauthenticated POST. The bcrypt hash exposure enables offline cracking; the TOTP exposure makes the 2FA defense moot for victims on the affected beta. If you run Automad, treat every admin credential as compromised, rotate passwords, and reset TOTP enrollment. The shape — public 'first-time setup' endpoint that never disables itself after first use — is a recurring CMS bug worth grepping for in any framework you maintain.

FUXA SCADA: unauthenticated project disclosure exposes server-side scripts and device configs; guest tokens read protected APIs in 'secure' mode

FUXA is a web-based SCADA / HMI platform. Its 'secure mode' isn't: when no JWT is presented, `verifyToken` mints a guest token signed with the server's secret and the API treats it as authenticated. The `GET /api/project` endpoint then returns the full project payload — server-side scripts, device IPs, OPC-UA endpoint URLs, modbus configs — to anyone who can reach the HTTP port. A companion advisory extends the same observation to `/api/alarms` and `/api/scheduler` with both missing-token and explicitly-invalid-token requests. SCADA / ICS exposure rules apply: assume any FUXA instance internet-reachable in the affected window has had its project data scraped, and rotate any device credentials embedded in those projects. Patch and restrict to a trusted network even after patching.

OpenCTI: organization admins escalate to full platform via graphQL userEdit relationAdd ACL gap

OpenCTI's per-organization admin role is supposed to be scoped to a single organization's data, but the graphQL `userEdit.relationAdd` mutation doesn't enforce that scope: an org admin can attach a higher-privileged user from a different organization into their own org, inheriting that user's privileges across the platform. The blast radius is full platform compromise — threat intel, indicators, reports, and any integrated SOAR. Tenants who share a single OpenCTI deployment across multiple business units or customers must patch before this becomes a tenant-isolation breach in production.

Pimcore continuation: SQL injection in DataObject composite-index import + WordExport authorization bypass

Two more on top of yesterday's Pimcore triple. The high is `compositeIndices.index_columns` getting concatenated verbatim into `ALTER TABLE ... ADD INDEX (...)` during DataObject class-definition import — any authenticated admin who can import a class definition can run additional `ALTER TABLE` subclauses against arbitrary Pimcore tables without needing stacked queries. The medium is the WordExport flow only checking the feature permission `word_export` and never the per-element view permission, so any backend user with the export feature can pull document content they don't have read access to. The Pimcore advisory stream is now a recurring source on the watch — if you operate Pimcore, lock the upgrade cadence and assume more advisories will land before the month closes.

Symfony Mailtrap, Mailjet, and LOX24 SMS webhook parsers never verify their signing secret — unauthenticated webhook event injection

Three webhook bridges with the same bug shape: `doParse(Request $request, #[SensitiveParameter] string $secret)` accepts the secret as an argument but never reads it. Mailtrap doesn't verify `X-Mt-Signature`. Mailjet and the LOX24 SMS notifier don't verify HTTP Basic auth against the configured secret. Any application wiring these parsers — even with the recommended signing secret configured — accepts unauthenticated POSTs as if they were genuine provider callbacks. Real-world impact: forged delivery / bounce / open / click / spam events, suppression-list corruption, deliverability-metric fraud, and potential downstream business logic abuse (auto-resubscribe loops, broken send-domain reputation triage). Patches land in the same Symfony point release as the broader hardening pass; reload the bridge containers after upgrade.

nono agent-sandbox: trivially escaped on Linux via D-Bus → systemd-run --user

nono is the sandbox tool the agent-coding community uses to box Aider, Claude Code, OpenCode, and similar agents that need `make` / `gcc` / shell access. Its Landlock+seccomp policy permits Unix domain sockets, which means the sandboxed process can speak to the per-user systemd D-Bus and call `systemd-run --user` — that starts an unsandboxed sibling, which then writes anywhere the user can write. The PoC is one line. If you run agent-coding tools under nono with any 'allow bash' profile, treat the sandbox as advisory rather than enforcing until the policy adds a D-Bus deny. Relevant for the Director-of-SRE-running-agents-locally crowd: do not assume your nono profile is actually constraining what Claude Code's bash tool can do on Linux right now.

Capsule (multi-tenant Kubernetes): TenantResource RawItems creates cluster-scoped resources, subresource path lets namespace hijack

Capsule's controller runs with cluster-admin, and its TenantResource RawItems processing forcibly sets a namespace on submitted manifests — but that does nothing for cluster-scoped kinds like `ClusterRole` or `ValidatingWebhookConfiguration`. A tenant admin who can submit a RawItems entry for a cluster-scoped resource therefore creates it with full cluster-admin authority, escaping tenant boundaries entirely. The companion low extends the pattern to namespace hijacking via the subresource path. If you use Capsule for multi-tenant separation, patch promptly and audit any cluster-scoped resources created by Capsule's service account since deployment — they may not all be yours.

opentelemetry-go: baggage parser no longer caps header length (DoS), Schema ParseFile leaks file descriptors

A merged PR removed the upfront baggage-string length check and the per-member size guard in `Parse`, so oversized or malformed `baggage` headers walk the entire input and forward each parse error to the global error handler (default-logging) — CPU, memory, and log-volume DoS against any service that doesn't pre-cap inbound header size at the proxy. Companion advisory: Schema's `ParseFile` leaks file descriptors per parse, slow-bleed FD exhaustion for any service that calls it on a hot path. Cap header sizes at your ingress; upgrade on the next release cadence.

Symfony hardening tail: YAML ReDoS + billion-laughs, HtmlSanitizer URI gaps, JsonPath ReDoS, polyfill-intl-idn Punycode equivalence, DomCrawler XXE, WebProfiler XSS

The tail of the Symfony hardening pass — a dozen low-severity advisories that share the same point release as today's high-severity webhook trio and yesterday's bigger tranches. The shape: YAML catastrophic backtracking in `Parser::cleanup()` and an exponential 'billion laughs' via collection-alias expansion; HtmlSanitizer's UrlAttributeSanitizer omits `action`/`formaction`/`poster`/`cite` so `javascript:` survives the strip; JsonPath `match()`/`search()` runs attacker-controlled regex (ReDoS); polyfill-intl-idn treats ASCII-only Punycode labels as equivalent to their decoded form (domain-similarity edge case); DomCrawler XXE local-file disclosure when `validateOnParse = true`; WebProfiler stored XSS via unescaped non-PHP file rendering in `CodeExtension::fileExcerpt()`. Each is a one-bug-deep fix; in aggregate the message is that this Symfony release should be treated as a single security upgrade — if you upgrade for the highs you already have these. Total advisories in this hardening pass now sit above twenty.

12:00 ET · Forenoon Watch

LiquidJS: template sandbox escape via valueOf filter → arbitrary code execution

The Liquid template engine for Node.js allows `1|valueOf` to resolve to `this` — the live evaluation context object — which a crafted template can then walk to reach Node internals and execute arbitrary code. No sandboxing or allow-list prevents the pivot. Any application that renders Liquid templates built from user-supplied input is a write-to-RCE path; CMS platforms, email templating, and SaaS report builders are the obvious blast radius. Audit every `liquid.render()` or `engine.parseAndRender()` call site that accepts untrusted template text, not just untrusted data; the vulnerability is in the filter evaluation chain, not the variable context.

Langroid SQLChatAgent: prompt injection → SQL injection → RCE via LLM-executed database commands

Langroid's SQLChatAgent passes LLM-generated SQL directly to the database without sanitization or query restrictions. An attacker who can influence the prompt — via document content, user input, or any RAG data source — can inject arbitrary SQL; if the database user has PostgreSQL's `pg_execute_server_program` or MySQL's `FILE` privilege, that becomes OS command execution. The 'AI framework executes LLM output as code' pattern keeps producing advisories; this one is notable because the injection surface is the data being analyzed, not just the user prompt. Upgrade to langroid >= 0.63.0; if you can't patch, restrict the DB role to SELECT-only and audit what privileges your SQLChatAgent connections carry.

Yamcs mission control: two authenticated RCE paths via unsandboxed Jython (JSR-223) and Nashorn script engines

Two independent script-engine paths in Yamcs (open-source spacecraft/satellite mission control) both compile and execute user-supplied algorithm text with no sandbox. The Jython path runs under JSR-223 with full system access; the Nashorn path constructs its ScriptEngine without a ClassFilter, so any authenticated user holding the `ChangeMissionDatabase` privilege can chain MissionDatabase algorithm override → arbitrary Java/OS code execution. Yamcs is niche but deployed at real space operations centers. The blast radius is limited by the `ChangeMissionDatabase` privilege requirement, but in default Yamcs configuration (no security.yaml) that means any user who can reach the API.

Kata Containers runtime-rs: guest-root to host-root escape via virtiofs FUSE channel

In runtime-rs standalone virtio-fs mode, Kata Containers launches the host `virtiofsd` daemon as root with `--sandbox none --seccomp none`. A guest-root process can send raw FUSE protocol requests directly to that daemon, mapping host filesystem paths and escaping the guest boundary entirely — guest-root becomes host-root. Confirmed on both QEMU and Cloud Hypervisor. If you run Kata with runtime-rs and virtio-fs filesystem sharing enabled, treat any guest workload as having host access until you've patched. The `cc-kbc` and `kernel-loopback` virtiofs configurations are not affected; only the standalone path hits this.

CrowdSec AppSec: body silently dropped for chunked and HTTP/2 requests — WAF body rules never fire

The CrowdSec AppSec component fails to read the HTTP body when `Content-Length` is not a positive integer — which covers all HTTP/1.1 chunked-encoding requests and most HTTP/2 requests sent without an explicit `content-length` header. Coraza WAF then evaluates against an empty body, so every rule targeting `REQUEST_BODY`, `BODY_ARGS`, `JSON`, `XML`, or `ARGS_POST` is a no-op for those traffic shapes. SQL injection and command injection payloads sent chunked pass straight through. This pairs badly with yesterday's gzip-bomb DoS on the LAPI — both are body-handling failures in the same release train. Upgrade; if you can't, force request downgrade to HTTP/1.1 with `Content-Length` at the upstream proxy to ensure body inspection fires.

Deno: stale TLS upgrade hook on connection retry causes plaintext traffic on what the app believes is an encrypted channel

When Deno's Node.js-compat TLS layer retries a connection with `autoSelectFamily` enabled and the first address-family attempt fails, the socket reinitialization reuses the TLS upgrade hook bound to the failed handle. The replacement TCP socket never completes the TLS handshake but the application's send path treats it as encrypted — credentials, tokens, and payload go over the wire in plaintext. The failure condition (first address-family down, second up) is realistic in dual-stack environments where IPv6 connectivity is broken. Deno services making outbound TLS calls in dual-stack networks are the primary exposure; check if `autoSelectFamily` is explicitly or implicitly enabled.

Symfony MonologBridge server:log listener: unauthenticated TCP connection triggers PHP object deserialization

Symfony's `server:log` console command opens a TCP listener on `0.0.0.0:9911` with no authentication and deserializes every incoming message as a PHP object via `unserialize()`. The command is documented as a development tool, but Docker Compose files and staging environments frequently leave it in the process table with a publicly reachable port. Any network-accessible `server:log` instance is a trivially weaponizable PHP object injection sink — depending on the installed gadget chain, this is often RCE. Run `ps aux | grep server:log` and `ss -tlnp | grep 9911` on every Symfony host; if it's there, kill it now. The upstream fix binds to `127.0.0.1` by default and adds a `--host` flag for intentional overrides.

compliance-trestle: cache path traversal in remote fetcher allows arbitrary file write → RCE

IBM's compliance-trestle library constructs local cache paths from HTTPS and SFTP URL path components without stripping `../` sequences. A malicious OSCAL profile that references `https://evil.com/../../../etc/cron.d/backdoor` will write the HTTP response body to `/etc/cron.d/backdoor` — attacker-controlled content, attacker-controlled path. The PoC chains this to cron job injection and SSH authorized_keys overwrite for RCE. Originally published 2026-04-30 with no patched version (latest then v4.0.2); today's coordinated batch (see separate high-severity item) shipped fixes alongside the SSTI, jinja --output traversal, profile-import file read, and SSRF advisories. Upgrade.

Pimcore cluster: unsafe PHP deserialization, unauthenticated WebDAV MOVE, and CustomReports authorization bypass

Three advisories across Pimcore v11 published in the same batch. The deserialization issue calls `unserialize()` in multiple locations on database column values and filesystem files without the `allowed_classes` restriction — if an attacker can write to those storage locations, object injection follows, and Pimcore's dependency surface has known gadget chains. The WebDAV MOVE endpoint performs asset mutations and deletions before checking for an authenticated Pimcore user, so any client that can reach `/asset/webdav` can move or delete assets unauthenticated. The CustomReports detail endpoint ignores sharing rules enforced at the listing layer, allowing low-privilege users to pull report data they shouldn't see. All three are addressed in the same Pimcore security release.

Symfony fourth tranche: SMTP CRLF injection, X509 identity spoofing, PdoAdapter SQL injection, CAS2 host-header redirect, HEAD access-control bypass, email header injection

The Symfony batch keeps growing. The highest-severity new addition is SMTP command injection via CRLF in `Symfony\Component\Mime\Address`: the constructor accepts RFC-5322 quoted-string local-parts containing raw CRLF bytes, which flow unescaped into SMTP commands — anyone who sends mail through Symfony Mailer with user-supplied addresses is a potential victim. X509Authenticator builds its Subject DN regex without anchoring, so `CN=Alice` matches `CN=AliceEvilCorp` — mTLS identity spoofing. PdoAdapter's `doClear($prefix)` concatenates caller-supplied prefix directly into a SQL `LIKE` query in the non-versioning path — SQL injection in your cache-clear calls. CAS2 handler derives the service URL from the client's `Host` header, enabling open redirect via header spoofing. HEAD requests bypass `#[IsGranted]` method filters because the check compares against `['GET']` rather than the effective method. All fixed in the same Symfony point release as the earlier tranches; if you haven't upgraded yet, the total advisory count for this Symfony hardening pass is now over a dozen.

AsyncSSH: AuthorizedKeysFile %u path traversal lets SSH username select arbitrary authorized_keys file

AsyncSSH 2.22.0 expands the `%u` token in `AuthorizedKeysFile` with the raw SSH username string before authentication completes. A server configured with `AuthorizedKeysFile authorized_keys/%u` — a pattern the AsyncSSH docs show as an example — can be made to read `authorized_keys/../../etc/passwd` by any client that sends a crafted username containing path traversal sequences. The attacker's goal is to find a world-readable file on the server that contains a line shaped like a valid SSH public key, then authenticate with the corresponding private key. Exploitation requires a traversable path with a usable file, so it's not trivially universal, but AsyncSSH servers using per-user key directory patterns should patch or validate usernames for `..` before the config-reload path.

06:00 ET · Morning Watch

Symfony continuation (third tranche): routing UrlGenerator bypass, HtmlSanitizer host-allowlist + BiDi spoof, SendmailTransport argument injection, OidcTokenHandler accepts JWTs without aud/iss/exp

Fifth wave from the same Symfony hardening pass that drove yesterday's quadruple. UrlGenerator route requirements are evaluated against unanchored regex alternations, so `(foo|bar)` matches off-site `//host` redirect targets. HtmlSanitizer's `allowLinkHosts` / `allowMediaHosts` checks against PHP's `parse_url` while the browser uses a different parser — the classic URL-parser-differential bypass — and even sanitised hrefs pass BiDi override characters through, so a rendered link can visually masquerade as a different domain. SendmailTransport takes recipient addresses straight into `sendmail` argv, so a `[email protected]` recipient becomes a debug-log filename — argument injection. OidcTokenHandler validates signature but not `aud` / `iss` / `exp`, so a valid OIDC JWT for service A authenticates against service B forever. Patches in the same point release as yesterday's batch (security.symfony.com advisories CVE-2026-…). If you ran the upgrade after yesterday's First Watch, you already have these.

CrowdSec LAPI: unbounded gzip decompression → memory-exhaustion DoS

Companion to yesterday's CrowdSec AppSec body-drop disclosure: the LAPI now adds a gzip-bomb decompression path with no size cap, so any client that can reach the LAPI can post a small payload that decompresses to gigabytes and OOM the agent. Realistic blast radius depends on where you've put the LAPI — internal-network deployments behind a trusted reverse proxy are far less exposed than anything terminating gzip at the LAPI itself. Patch on the same release train as the AppSec disclosure; if you can't roll tonight, cap request body size at the upstream proxy and reject `Content-Encoding: gzip` until you've upgraded.

Kirby CMS: content locks endpoint discloses IDs and email addresses of users the caller cannot otherwise see

Fifth Kirby disclosure in the running batch. The `users.access/list` content-locks endpoint enumerates anyone currently editing a piece of content — including users the calling role has no `users.read` permission for — leaking user IDs and email addresses in plain text. Information disclosure rather than authorisation bypass, so the impact is reconnaissance rather than direct compromise; the right framing is that Kirby's per-role user visibility model now has another corner that doesn't honour it. Patched alongside the Kirby triple from yesterday — if you upgraded for the path traversal + XSS + arbitrary-method advisories you already have this fix; otherwise note that this batch has now grown to five and the upgrade has accumulated security-by-default changes worth re-reading the changelog for.

Morning shape: KEV steady, RSS quiet — disclosure pipeline still flushing yesterday's Symfony/Kirby/CrowdSec batch

CISA KEV catalog version is unchanged from yesterday's Last Watch — the Nx Console / TanStack / Daemon Tools Lite trio added 2026-05-27 remains the front of the queue and no further adds have landed overnight. RSS is quiet by midnight-Eastern standards: Socket, Phylum, Aikido, Bleeping, and The Hacker News produced nothing matching the watch keyword set that wasn't already in yesterday's First Watch (GlassWorm takedown, mouse5212, codexui). The morning's new material is therefore entirely disclosure-side: GHSA's Symfony mass-publication batch from yesterday afternoon kept publishing late into the night, adding a fifth tranche of mediums plus a Kirby content-locks PII disclosure and a CrowdSec LAPI gzip-bomb DoS. Forenoon and First Watch will tell us whether US-business-hours brings anything active or whether the week's npm-poisoning narrative pauses here.