v vanemmerik.ai / SUPPLY-CHAIN
Supply Chain · Watch Wednesday · 09 September 2026 End-of-day synthesis 4 watches · 41 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 — CISA's twin KEV adds for Citrix NetScaler and Cisco's firewall manager — both under three-day patch clocks — remain tonight's top priority, even after a late-evening batch of nine high-severity GHSA disclosures, including an MCP-server RCE and a LAN-exposed ESPHome dashboard, pushed the day's high count past every other evening this series has logged.

Tonight's operational story hasn't moved since First Watch: Citrix NetScaler and Cisco's Firewall Management Center/Security Cloud Control both picked up near-identical alternate-path authentication bypasses on CISA's KEV list today, each under an aggressive three-day patch clock. A Fortinet heap overflow and a Chromium V8 sandbox escape round out the day's four KEV adds; none of that changed in the last three hours.

Late escalation at 21:00 ET: nine more high-severity GHSA disclosures landed between First Watch and this check-in, the largest single after-hours batch this series has logged. functype-mcp-server's set_functype_version tool interpolates a caller-supplied version string directly into a pnpm install specifier with no validation, and pnpm/npm alias syntax turns that into remote code execution — audit anything that wires an MCP tools/call endpoint to a package manager. ESPHome Device Builder's Home Assistant add-on bound its ingress dashboard to every LAN interface instead of loopback, so any device on the local network gets the full unauthenticated dashboard; the rest of the batch — an Identrail cross-tenant IDOR, a Komari CSRF, unauthenticated task execution in @yeger/turbo-graph, an API-key leak in nuxt-ollama, two more Open WebUI DoS bugs, a GeoNetwork SSRF, and a webhookd header-injection — is real but narrower: single-package, no confirmed exploitation, patch on your normal cadence.

→ Operational priority for the night NetScaler and Cisco FMC/SCC against the September 12 KEV deadline still come first; after that, check whether functype-mcp-server or ESPHome Device Builder are anywhere in your stack, since both are unauthenticated-exposure bugs with patches already out.

21:00 ET · Last Watch

Identrail: client-supplied GitHub App installation_id lets one tenant hijack another's installation

identrail's GitHub App connection-completion endpoint trusts a client-supplied installation_id and mints an installation access token for it without checking that the installation belongs to the calling workspace. Any authenticated tenant can link another identrail customer's GitHub App installation into their own workspace — a straightforward cross-tenant IDOR sitting in a multi-tenant SaaS integration path. Patch to 1.0.2, and audit any other endpoint that resolves a caller-supplied ID against a different tenant's resource without an ownership check.

@openhop/server: unauthenticated path traversal reads and deletes arbitrary YAML files

@openhop/server joins unsanitized HTTP route parameters straight into path.join() when resolving flow YAML files, so an unauthenticated attacker can read or delete arbitrary .yaml files outside the configured flow directory. The default CORS policy (origin: true) means a victim's browser can be made to trigger the delete path too. No patched version is listed yet — restrict network exposure of the OpenHop server until one lands.

ESPHome Device Builder: HA add-on binds its ingress dashboard to every LAN interface, not just loopback

ESPHome Device Builder's Home Assistant add-on binds its ingress dashboard to 0.0.0.0 instead of loopback, and because the add-on runs in host network mode for mDNS, that also exposes the host's LAN interface. Any device on the local network gets the full dashboard with no credentials — the ingress design assumed the supervisor's upstream auth was the only thing reachable. Update past 1.0.10, and don't assume HA add-on ingress is loopback-only without checking the add-on's network mode.

functype-mcp-server: unvalidated version string in an MCP tool becomes RCE via pnpm package-alias syntax

functype-mcp-server's set_functype_version MCP tool interpolates an unconstrained caller-supplied version string into an npm package specifier and installs it via pnpm add with no validation. pnpm/npm alias syntax (file:, npm:) turns that version string into arbitrary code execution the moment an MCP client calls the tool. If you run MCP servers that wire tool arguments into package-manager commands, treat this as the canonical bad example and go audit them.

Joker linter executes project-local .jokerd/linter.* files just from linting an untrusted repo

joker --lint walks upward from the linted file looking for a .jokerd/ directory and executes any linter.* files it finds there before linting — so linting a file inside an untrusted repo checkout runs that repo's code. CI jobs and editor integrations that auto-lint on checkout are the realistic trigger path. Patch to 1.8.2, and treat any "linter finds and runs a repo-local config file" pattern as a supply-chain smell worth grepping your own tools for.

Komari: management API relies on a cookie with no SameSite/Secure and no CSRF check

Komari's session_token cookie ships without SameSite or Secure attributes, and every /api/admin/ endpoint relies on that cookie alone with no CSRF token or Origin check. Modern browsers' default SameSite=Lax mitigates but doesn't eliminate the cross-site risk. Upgrade past the fixed commit, and don't rely on browser defaults as your only CSRF control on an admin surface.

@yeger/turbo-graph: unauthenticated, network-exposed task execution via /api/run

@yeger/turbo-graph's embedded dev server listens on all interfaces by default (0.0.0.0:29312), and its /api/run endpoint executes attacker-supplied Turborepo task names via spawn() with no auth, CSRF check, or allowlist. Any adjacent-network attacker gets unauthenticated task execution against your monorepo tooling. Update past 2.8.8, and don't run dev-time build tooling on anything but loopback.

Nuxt Ollama leaks the Ollama API key to every browser client via public runtime config

nuxt-ollama merges all module options — including the Ollama API key — into Nuxt's public runtime config, which gets serialized into the SSR HTML payload. Any unauthenticated visitor who loads the page gets the API key in plaintext from window.__NUXT__. Update past 1.3.1, and grep your own Nuxt modules for anything that puts secrets in runtimeConfig.public instead of the private half.

GeoNetwork's SLD tooling endpoint is an unauthenticated SSRF foothold

GeoNetwork's SLD tooling endpoint (POST /api/tools/ogc/sld) takes a caller-supplied WMS server URL and issues a server-side GET to it with no validation, unauthenticated. That's a textbook SSRF foothold into whatever internal network the GeoNetwork server sits on. Patch, and in the meantime put an egress allowlist in front of anything that fetches a caller-supplied URL server-side.

Open WebUI: any authenticated user can hang the server via a cyclic chat tree deletion

Open WebUI's chat-tree walk after a message delete doesn't track visited nodes, so any default-role user can store a self-referential chat tree and hang the server's request loop by deleting a message from it. That's a single-request DoS available to any authenticated user, not just admins. Update to 0.11.1.

Open WebUI: unvalidated redirect targets let server-side fetches reach blocked and internal hosts

Open WebUI's excluded-host and private-address checks on server-side fetches don't apply to HTTP redirect destinations, so on deployments with redirect-following enabled, an authenticated user can point a fetch at a page that redirects into a blocked or internal host. Same family as the message-delete hang disclosed in the same batch — Open WebUI's server-side fetch path is getting a second look this week. Update to the patched release, and disable redirect-following if you can't patch immediately.

webhookd forwards HTTP headers into shell variables unchecked when Basic Auth is disabled

webhookd forwards all incoming HTTP headers into the webhook script's shell environment as variables when Basic Auth isn't configured — a classic header-to-shell-variable injection if you're running it behind an unhardened reverse proxy without the auth middleware on. Turn on Basic Auth or upgrade past 1.22.0, which strips the injection path regardless.

18:00 ET · First Watch

CISA adds a Citrix NetScaler authentication bypass to KEV — due date September 12

CISA catalogued CVE-2026-19490 today: NetScaler ADC/Gateway configured as an AAA virtual server or Gateway (SSL VPN, ICA Proxy, CVPN, RDP Proxy) can be reached by an unauthenticated attacker via an alternate path or channel that skips authentication entirely. NetScaler auth-bypass chains are a recurring initial-access vector for ransomware crews, and the three-day KEV due date signals CISA sees active or imminent exploitation. If you run NetScaler as an AAA/Gateway virtual server, patch by September 12 and check CTX696939 for indicators of prior compromise, not just the patch.

A second alternate-path auth bypass hits KEV the same day — Cisco Firewall Management Center and Security Cloud Control

CISA also added CVE-2026-20079 today, an authentication bypass in Cisco FMC and Security Cloud Control firewall management using the identical bug class — alternate path/channel — as the NetScaler entry above, two unrelated vendors' management-plane auth logic failing the same way on the same day. FMC is the control plane for a Cisco firewall fleet, so a bypass there is a blast-radius multiplier: compromise the manager and you have a foothold toward every firewall it manages. Patch FMC/SCC by the September 12 due date and treat any internet-reachable FMC management interface as at-risk until then.

Fortinet FortiOS heap-based buffer overflow (CVE-2025-25249) added to KEV

CISA catalogued a heap-based buffer overflow spanning FortiOS, FortiSwitchManager, and FortiSASE that lets an attacker execute unauthorized code via specially crafted packets — a 2025-numbered CVE only now confirmed under active exploitation. Fortinet edge devices are a standing target for both opportunistic and targeted campaigns, and a heap overflow reachable by network packets on a perimeter device is as bad as the category gets. Patch by the due date and check FortiGuard's advisory (FG-IR-25-084) for exact affected builds — don't assume a different Fortinet patch this year already covers it.

Chromium V8 out-of-bounds write added to KEV — patches Chrome, Edge, and every other Chromium-based browser

A V8 out-of-bounds write lets a crafted HTML page execute code inside the renderer sandbox, and today's KEV add confirms active exploitation; the fix already shipped in Google's stable-channel update, so patching is really a question of confirming auto-update ran. Every Chromium-based browser inherits the bug, not just Chrome, so fleet-wide compliance can't be checked from one vendor's release notes alone. Verify managed Chrome/Edge/Opera builds are past the patched V8 version by September 23, especially any endpoints where policy blocks browser auto-update.

smol-toml's parser spins forever on a six-byte malformed TOML document

A value inside an array or inline table followed by a comment with no trailing newline sends smol-toml's parser into an infinite loop instead of erroring — parse('a=[1 #') never returns and pins the CPU at 100%. Any service parsing TOML from an untrusted source (config uploads, CI manifests, plugin metadata) inherits a one-line denial-of-service. Upgrade to 1.7.1; if you can't patch immediately, wrap any TOML input that didn't come from your own repo in a parse-time budget.

WeasyPrint's url_fetcher sandbox has channels that ignore it entirely

url_fetcher is WeasyPrint's documented way to block file:// and internal-host access when rendering untrusted HTML/CSS to PDF, but write_pdf()'s xmp_metadata=[url] channel (and a second one per the advisory) builds a fresh default fetcher instead of using the caller's configured one, silently bypassing the restriction. Any "render user-supplied HTML to PDF" feature relying on url_fetcher as its SSRF control is exposed on those paths regardless of configuration. Upgrade to 70.0, and don't assume a configured url_fetcher covers every write_pdf() call until you've checked which channel your code uses.

SQLAdmin's sortBy parameter ignores the sortable-column allow-list

ModelView.sort_query() resolves the attacker-controlled sortBy query parameter with getattr() and feeds it into order_by() without checking column_sortable_list, so a request can sort by any column — including ones hidden from column_list — and, via a dotted path, by columns on related models. Row order then leaks the value of a column the admin never intended to expose. Upgrade to 0.27.1, and don't treat column_sortable_list as a security boundary on unpatched versions.

containerd's CRI ExecSync leaks a goroutine every time a probe's child process outlives it

The stdio-drain phase of containerd's CRI ExecSync has no timeout or context cancellation, so exec probes or lifecycle hooks that spawn a background child process keep drain goroutines blocked indefinitely; repeated invocations — which is exactly what liveness/readiness probes do — leak goroutines and host memory until the node degrades. It's a slow-burn node-level DoS with no attacker input required beyond a normal-looking probe configuration. Upgrade containerd (2.0.12 / 1.7.35 / 2.2.8 / 2.3.5 depending on your line), and audit exec probes for background/daemonizing child processes.

GitHacker will follow a malicious .git server's crafted HEAD ref off its own output directory

GitHacker (a tool for recovering source from an exposed .git directory) doesn't validate path segments parsed from an attacker-controlled .git/HEAD before joining them onto its output path, so a malicious Git server it connects to can make it read arbitrary local files; it doesn't exfiltrate contents wholesale, but its recovery loop turns any 40-character hex substring into an outbound HTTP GET, giving an existence oracle plus hex-fragment exfiltration. This flips the usual trust model — GitHacker is normally pointed at someone else's exposed repo, but here that server can attack the operator back. Upgrade past 1.1.7, and don't point GitHacker at a Git server you don't trust.

decidim-elections renders election question titles as trusted HTML

A process-scoped election admin — a relatively low-privilege role — can store arbitrary HTML in a question's title/body, and the public elections UI's question_title helper renders it unescaped, giving stored XSS against every voter who views that question. On a civic e-voting platform, stored XSS in front of voters is a trust and integrity issue as much as a technical one. Upgrade to 0.32.0, and audit existing election questions authored by non-fully-trusted admins for injected markup.

gix-sec's safe.directory check doesn't apply to a Windows process running as full admin

gitoxide's gix-sec is supposed to refuse to operate in a local repository it doesn't consider trusted — not owned by the current user, not in safe.directory — the same protection Git itself has, but on Windows a process running with full administrative rights is wrongly treated as trusting every location, so it will execute repository-configured commands from a repo a limited user account controls. That defeats the exact scenario safe.directory exists for: an elevated process wandering into a directory a non-admin attacker planted a malicious .git config in. Upgrade past 0.13.2 if any Rust tooling using gix-sec runs elevated on Windows near untrusted repositories.

ASP.NET Core's IIS out-of-process hosting doesn't constrain request decompression

The IIS Middleware for ASP.NET Core's out-of-process hosting doesn't properly bound decompression of certain compressed request types, giving an unauthenticated remote attacker a denial-of-service (CVE-2026-69304) — a separate bug from the DiaSymReader/.NET batch covered earlier today, same vendor and day, unrelated root cause. Patch the affected Microsoft.AspNetCore.Server.IISIntegration versions (8.0 through 8.0.30, 9.0 through 9.0.19, 10.0 through 10.0.11) if you host ASP.NET Core out-of-process behind IIS.

n8n's sub-workflow caller-restriction setting doesn't apply when the workflow is attached to an Agent as a tool

A workflow's "this workflow can be called by" restriction is enforced by the Execute Workflow node but was never consulted on the Agent-tool call path, so anyone who could build an Agent in n8n could invoke a workflow its owner had explicitly restricted and read back its output. AI-agent tooling is accreting its own permission model on top of the platform's existing one, and this is a case where the two didn't match — worth checking for the same pattern anywhere else an agent can reach a restricted resource. Upgrade to 2.37.7 or 2.38.2.

morgan's log-forging fix missed three Unicode line separators

The 1.11.0 fix for morgan's log injection neutralized C0 control characters, DEL, and backslash in logged request data, but left U+0085 (NEL), U+2028, and U+2029 unescaped; those code points are reachable through the request URL, User-Agent, Referrer, arbitrary req[header] values, and Basic-auth usernames, and several common log viewers and terminals treat them as real line breaks. An attacker can still forge fake log lines to mislead whoever reads the access log or a downstream SIEM parser keyed on line boundaries. Upgrade to 1.12.0 if you rely on morgan's sanitization as a control against log forging, not just readability.

LF Edge eKuiper ships three same-day advisories: path-traversal file deletion, SSRF, and a self-XSS

eKuiper's plugin-installation endpoint accepts a path-traversal payload that deletes arbitrary files and directories, its "external service" feature is SSRF-able, and a third bug allows self-XSS when creating an external service — three distinct holes in the same edge-stream-processing engine's admin surface disclosed together. eKuiper commonly runs at the edge with elevated filesystem and network access, so the path-traversal deletion is the real availability risk on any node where the admin API is reachable. Patch the eKuiper install and don't expose its plugin/external-service admin endpoints without authentication in front of them.

12:00 ET · Forenoon Watch

Microsoft.DiaSymReader.Native ships three same-day advisories: two heap overflows in PDB parsing, one in Portable PDB parsing

Microsoft disclosed three CVEs (CVE-2026-69522, CVE-2026-69439, CVE-2026-71328) against Microsoft.DiaSymReader.Native in one batch, each an out-of-bounds heap write triggered by a malformed PDB, Portable PDB, or MSFZ PDB file (CVSS 8.8, requires user interaction). Debug symbol files travel alongside NuGet packages and crash-dump tooling, so a project that loads third-party or CI-produced PDBs inherits the same untrusted-input risk as any other dependency, not just its source code. Treat PDB files from outside your own build pipeline as untrusted and update Microsoft.DiaSymReader.Native before opening or processing them.

TypeSpec's OpenAPI3 emitter lets a crafted @versioned enum member write files outside the output directory

@typespec/openapi3 interpolates a @versioned enum member's value straight into the output filename without stripping path separators or traversal sequences, and the compiler's emitFile() writes it without checking containment under emitterOutputDir — no attacker-controlled JS or extension required, just a crafted .tsp input. Anyone compiling TypeSpec definitions from a third-party or contributor-supplied schema can have arbitrary YAML/JSON files created or overwritten outside the intended output tree. Upgrade the patched compiler/openapi3/http release, and treat any externally-sourced .tsp file as untrusted input to a file-writing tool, not just a schema.

Tiptap's Markdown attribute parsers are quadratic — a 20KB crafted token pins the event loop for over a second

@tiptap/core's default block and inline Markdown-attribute parsers use unanchored greedy regexes that rescan repeated quoted-prefix or bare-word runs; a 20,508-byte crafted atom-block token took roughly 1.4 seconds to parse against 0.29ms for an equal-length control, and a 32,776-byte inline token took roughly 2.2 seconds. Any editor that renders user-supplied or collaboratively-edited Markdown through createBlockMarkdownSpec, createAtomBlockMarkdownSpec, or createInlineMarkdownSpec is one paste away from a frozen event loop. Upgrade @tiptap/core, and if you can't patch immediately, cap the size of untrusted Markdown before it reaches the parser.

Infostealer logs are turning into a market for replayable AI API tokens that skip MFA entirely

Malware families like Lumma Stealer and Vidar are harvesting credentials, session tokens, and API keys from compromised endpoints, and researchers report those logs being repurposed specifically to reach AI provider accounts — Google and Anthropic named among them — because a replayed session or API token authenticates without ever touching the MFA prompt that would stop a straight credential-stuffing attempt. It's the same infostealer-log economy that already feeds initial-access brokers for ransomware, now pointed at AI accounts with API keys and billing attached instead of just SaaS logins. If your CI or agent tooling holds long-lived AI provider API keys on developer endpoints, treat them like production secrets — rotate on any endpoint-compromise signal, not just on password reset.

06:00 ET · Morning Watch

Windows ML CLI: CORS wildcard plus --trust-remote-code turns a local dev server into drive-by RCE

winml-cli's local serve API binds to localhost but sets allow_origins to a wildcard, so any website the developer has open can reach it cross-origin; combined with the build/config commands' --trust-remote-code flag, a malicious page can point the CLI at an attacker-controlled model repo and get arbitrary code execution on the developer's machine. This is the classic 'localhost service with permissive CORS' shape that's bitten other local AI/ML tooling this year — binding to 127.0.0.1 gives a false sense of isolation when the browser is the attacker's delivery mechanism. If you run winml-cli locally, update past the vulnerable range and never combine --trust-remote-code with an unreviewed model source.

phpseclib's pure-PHP X25519 leaks the private scalar one Montgomery-ladder step at a time

phpseclib's field arithmetic performs a data-dependent conditional reduction on every ladder step, so an observer timing the operation — or just counting libgmp calls — recovers the 251-bit clamped private key; researchers recovered 20 of 20 test keys from 32 timing observations, and a call-counting observer needed only one. This isn't a low-order-input trick — it works against RFC 7748's own base point with zero attacker-chosen input, so rejecting bad public keys doesn't help, which is why the impact outweighs the GHSA-assigned medium score. If you use phpseclib's pure-PHP X25519 anywhere an attacker can measure timing or instruction counts (shared hosting, co-located containers, side-channel-exposed KMS-adjacent code), treat the key as burned and patch now.

MongoDB PHP driver: unsanitized dots and NUL bytes in database/collection names can retarget an operation

The MongoDB PHP library doesn't reject '.' or NUL bytes in database or collection name parameters, so untrusted input passed into those fields can redirect an operation at a different database or collection than the one the application intended. It's a narrow but real injection primitive — anywhere a tenant ID, username, or other user-controlled string is interpolated directly into a collection name (per-tenant collections in multi-tenant apps are the classic case) is exposed. Validate database/collection names before they reach the driver and upgrade to 1.21.4 / 2.4.1.

SVGO's removeScripts sanitizer has two more bypasses: namespaced anchors and foreignObject HTML

Two same-day advisories against SVGO's opt-in removeScripts plugin: it missed executable href values on namespace-prefixed anchors (<svg:a>) and URLs carrying embedded tab or newline characters, and separately never inspected HTML inside <foreignObject> at all — onload, srcdoc, and formaction all pass through untouched. SVGO markets itself as an optimizer, not a sanitizer, but pipelines that use removeScripts as their only defense against untrusted SVG uploads get XSS straight into the browser from either bypass. If removeScripts is your only untrusted-SVG defense, upgrade now and don't treat an SVG 'sanitized' before the patch as safe.

HTTPX2 ships two protocol-framing bugs: unbounded decompression and a Content-Length/Transfer-Encoding collision

HTTPX2 fully inflated each 64 KiB socket read before yielding bytes to the app, so a single compressed chunk at DEFLATE's ~1032:1 ratio balloons to roughly 64 MiB in one allocation — streaming the response doesn't help, since the amplification happens before your code sees anything. Separately, the client's setdefault()-based header logic can auto-generate a Content-Length alongside a caller-supplied Transfer-Encoding, handing an intermediary two conflicting framing headers to disagree about, which is the setup for request smuggling. Anywhere HTTPX2 fetches from an untrusted or attacker-influenced origin, upgrade to 2.12.0+ and audit for manual Transfer-Encoding headers on outgoing requests.

gRPC-Go's xDS stack: a missing-header panic and a case-sensitivity bug that lets DENY rules fail open

A request with neither :authority nor Host crashes any gRPC-Go server built with xds.NewGRPCServer() — the routing interceptor indexes into an empty authority slice and panics without recovery, killing the whole process, not just the one RPC. Separately, the xDS RBAC HTTP filter lowercases incoming header names before matching but not the policy's own header key, so a DENY rule written as X-Role never matches an incoming x-role header and silently fails open, and the same casing trick evades the guard against grpc--prefixed headers. If you run gRPC-Go with xDS, patch the DoS immediately and re-audit any RBAC policy referencing a mixed-case header name — it may have been failing open since it was written.

Nodemailer ships four same-day advisories: a CPU-freezing address parser and three ways to smuggle mail past a domain allow-list

The address parser runs in O(n²) time, so one ~1.5MB address value in a To/Cc/Bcc/From/Reply-To header pins the event loop at 100% CPU for tens of seconds with no cooperating receiver required — a pure availability bug on the default code path. The other three are allow-list bypasses: a raw Punycode codec that resolves IDN domains differently than every UTS-46-conformant parser (browsers, Node's own domainToASCII), an RFC 5322 comment like (x) inside a domain that gets concatenated instead of treated as folding whitespace, and a legacy resolveContent(data, key, callback) signature that silently drops the disableFileAccess/disableUrlAccess sandbox flags. Anywhere you validate a recipient domain before handing the address to Nodemailer, or expose resolveContent to untrusted message content, re-test against these three parsing differentials and upgrade past the vulnerable range.

js-yaml's merge-key CPU limit doesn't count empty mappings, so the limit doesn't limit anything

maxTotalMergeKeys was meant to cap the CPU cost of YAML merge keys (<<), but it only counts keys inside non-empty mappings — repeatedly merging a large anchor of empty mappings does O(N×K) work while the tracked counter stays at zero. Any service that parses untrusted YAML with js-yaml and relies on maxTotalMergeKeys as its DoS guard has no real limit in place today. Upgrade js-yaml, and don't trust maxTotalMergeKeys alone on unpatched versions — pair it with an overall parse-time budget.

Hono ships three same-day advisories: a still-incomplete path-traversal fix, unbounded body-parser nesting, and fragment/query confusion

The fix for an earlier toSSG() path-traversal bug only collapsed a single parent-directory segment; a route parameter with enough consecutive parent-directory sequences still writes static-export files outside the configured output directory. Separately, parseBody()'s dot-notation field-name expansion has no depth or count limit, so a normally-sized request body can allocate an object graph large enough to exhaust the heap, and the query parser reads parameters after a # fragment that every proxy, cache, and browser treats as invisible — opening a cache-key and access-control interpretation gap. None of the three needs anything exotic to trigger; if you run Hono with toSSG(), an unbounded parseBody(), or a cache/allow-list that trusts the query string, patch and re-check those assumptions specifically.