v vanemmerik.ai / SUPPLY-CHAIN
Supply Chain · Watch Saturday · 29 August 2026 End-of-day synthesis 4 watches · 18 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 — Spoofable client headers undo access control in three unrelated projects today, while Plone takes the day's only critical slot with a matched pair of import-triggered SSRF/DoS/XSS bugs.

The evening catch-up fetch came back empty — nothing new since the Forenoon pass — so today's shape is set entirely by this morning's GHSA batch. Two Plone advisories take the day's only critical slot: importing an attacker-influenced iCalendar file or RSS feed lets any logged-in editor take the site down, SSRF the internal network, and plant stored XSS.

The throughline across three unrelated highs is spoofable identity: phpSysInfo's IP allowlist trusts X-Forwarded-For ahead of REMOTE_ADDR, 9router's local-request exemption trusts a spoofed Host header — its fifth distinct auth-bypass class disclosed this year — and Bifrost's SSRF deny-list misses CGNAT and 6to4/NAT64 ranges that route straight to cloud metadata. All three treat a client-controlled value as if it were a verified network position. Piccolo-admin and Weblate round out the high tier with narrower, already-authenticated escalation paths rather than anything reachable pre-auth.

→ Operational priority for the night audit any service that gates access by X-Forwarded-For, Host header, or an internal-IP allowlist — today's batch is a reminder that client-supplied network identity is not identity.

06:00 ET · Morning Watch

Plone's iCalendar and RSS-portlet imports both let a logged-in editor take the site down, SSRF the internal network, and plant stored XSS

Two independent Plone advisories share the exact same failure shape: importing attacker-influenced content — an iCalendar file via plone.app.event, or a feed URL via plone.app.portlets' RSS portlet — lets any logged-in editor point Plone at an oversized file or feed, exhausting memory to take the whole site offline, probe the internal network and open ports (SSRF), and inject stored XSS through crafted URL/javascript: fields (CVE-2026-55247, CVE-2026-55248). Neither needs admin rights, just the routine editor-level ability to import an event or add a portlet — the portlets advisory explicitly calls out the event one as the same bug shape. Patch plone.app.event to 6.0.1/5.2.4 and plone.app.portlets to 7.0.2/6.0.4/5.0.8, and until then restrict iCal-import and manage-portlets permissions to Manager/Site Administrator only.

Incus lets an attacker copy instances and custom volumes out of projects they can't access, just by knowing the project and object name

Two matching authorization gaps in Incus: the instance-copy and custom-volume-copy endpoints check that the caller can create in the target project but never check that they can view the source project's object, so knowing a project name and an instance or volume name is enough to copy someone else's secrets into your own project (CVE-2026-55622, CVE-2026-55621). The copy has to land on the same server, but nothing stops the attacker moving it off afterward. If you run multi-tenant Incus with project-restricted certificates, this is a live cross-tenant data-exposure path until patched — audit recent cross-project copy operations in your logs.

Weblate's team-scoping API lets a project manager grant themselves access to projects they don't own; a second bug leaks which private projects exist

Weblate's team API didn't validate project- and workspace-scoped team configurations, so an authenticated project manager could construct a team config granting read access to a project they have no legitimate access to (CVE-2026-55228, independently reported by four researchers). A second, lower-severity bug returns HTTP 403 instead of 404 on several endpoints for private projects, letting anyone confirm a private project's existence by status code alone (CVE-2026-55227). Patch both — the first is a real cross-project confidentiality bypass, the second is reconnaissance fuel for the first.

9router's LLM proxy gets two more unauthenticated bypasses — a spoofed Host header and a /codex rewrite both skip the API-key gate

9router's local-request exemption trusts the client-controlled Host header, so sending Host: localhost gets a remote, unauthenticated caller treated as local and granted full /v1 proxy access with no API key and no login (CVE-2026-55641); a second, independent bug routes /codex/* to the same backend as the protected /v1 endpoints, but the auth middleware's protected-path list doesn't include /codex, bypassing the same gate a different way (CVE-2026-55638). Either one hands an attacker your stored provider API keys for a free LLM relay, and the Host-header bug also opens unauthenticated SSRF via the built-in searxng provider — this is at least the fifth distinct auth-bypass class disclosed against 9router this year. Don't rely on 9router's local-request detection; front it with real network-level access control and patch both paths.

klever-go: a percentage-royalty split of exactly 100% skips the sender's debit entirely, minting the transferred asset off the books

klever-go's percentage-royalty transfer path collects the royalty pool from the sender only after the split loop, and only after an early-return guard that fires when the computed payable amount is zero or negative — a split configured at exactly 100% drives that amount to zero and hits the early return before the sender is ever debited (CVE-2026-55763). The recipient keeps the full royalty and the sender pays nothing, so every transfer of the affected asset mints new value with no supply-counter update; the sibling fixed-royalty path debits first and isn't affected. If you operate or validate on a Klever chain, treat any asset with a 100%-split royalty config as a live inflation vector until patched.

alos-http: a single unauthenticated request with a path starting in "?" crashes the whole server process

alos-http's request-path sanitizer strips the query string and then indexes the first byte of what's left without checking it isn't empty, so a path of just "?" produces an out-of-bounds panic that fires before any handler or recovery middleware can catch it — the entire process crashes and every connection drops (CVE-2026-55484). It's reachable over HTTP/1.1, HTTP/2, and HTTP/3 with one unauthenticated request, no special client needed. Patch before exposing any alos-http-based service to the internet; this is a one-packet denial of service against the whole process, not just a request.

Protego's robots.txt parser has exponential-backtracking ReDoS — a crafted Disallow line freezes any crawler that uses it

Protego translates every asterisk in a robots.txt Allow/Disallow directive into a lazy .*? regex fragment, so a directive value with enough asterisks produces a pattern that backtracks exponentially against a matching URL (CVE-2026-55520). A robots.txt with a single crafted Disallow line is enough to hang any crawler's can_fetch() call for as long as the attacker wants. If you fetch robots.txt from untrusted or third-party hosts before crawling, put a timeout around the parse/match calls rather than trusting the library alone; there's no patched version referenced in the advisory.

PowSyBl Core's local command executor builds shell commands by string concatenation — straightforward OS command injection

PowSyBl's Unix and Windows local-command-executor implementations build command strings by concatenation and run them through bash -c / cmd /c, so any string argument or environment variable that reaches the executor — via public APIs like LocalComputationManager.execute or the action-simulator and security-analysis CLI tools — can break out and run arbitrary shell code as the JVM user (CWE-78, secondary CWE-88 via env vars). None of the public method signatures document that their List<String> arguments undergo shell interpretation, so any caller forwarding less-trusted data inherits the bug silently. If you embed PowSyBl's simulation tooling and pass through user- or file-supplied parameters, audit for this before the patched release lands.

phpSysInfo's IP allowlist trusts X-Forwarded-For and Client-IP ahead of REMOTE_ADDR — trivially spoofable, defeating the only access control it has

phpSysInfo's PSI_ALLOWED IP allowlist resolves the client IP from the attacker-controlled X-Forwarded-For and HTTP_CLIENT_IP headers before ever falling back to REMOTE_ADDR, so sending X-Forwarded-For: <an-allowed-ip> impersonates a trusted address and exposes full system information to anyone (CVE-2026-55584). This is the only IP-based restriction the application offers, and it's defeated with one header on every version up to and including current main. If PSI_ALLOWED is the only thing standing between phpSysInfo and the internet, put it behind a real reverse-proxy allowlist or authentication instead.

Bifrost's SSRF deny-list misses CGNAT, 6to4, NAT64, and site-local ranges — all routes to cloud metadata via a crafted image URL

Bifrost's isPublicIP check, which gates outbound fetches for multimodal image/document URLs in Bedrock and Vertex requests, classifies Carrier-Grade NAT (100.64.0.0/10), IPv6 6to4 (2002::/16), NAT64 (64:ff9b::/96, 64:ff9b:1::/48), and deprecated site-local (fec0::/10) as public and lets them through (CVE-2026-55245). An attacker who controls an image URL in a request body can reach cloud instance-metadata endpoints via the 6to4/NAT64 embeddings of 169.254.169.254 — the DNS-rebinding protection, redirect re-validation, and size/timeout caps are all fine, this is purely a gap in one classification function. If you run Bifrost in front of Bedrock or Vertex with untrusted image/document URLs, treat this as a live metadata-exfiltration path until the deny-list is patched.

piccolo-admin: a non-superuser can list every live session token and use one to self-promote to superuser

piccolo-admin's superuser_validators helper blocks PUT/PATCH/DELETE/POST on the sessions table for non-superusers but doesn't block GET, and the sessions table stores live tokens in plaintext without the secret=True flag — so any non-superuser admin can GET the sessions table, read every user's live session token, replay one as their own cookie to impersonate that user, and then write superuser=true on their own row (CVE-2026-55485). It's reachable on the realistic, documented setup where a deployer adds Sessions and User tables to create_admin() so superusers can monitor and revoke sessions. If your piccolo-admin config exposes the sessions table to any non-superuser, pull that access now and rotate active sessions before patching.

A second wave from yesterday's MariaDB cleartext-password batch — five more CVEs across the server, JDBC, and R2DBC connectors

More advisories from the same MariaDB disclosure batch covered yesterday: R2DBC leaks passwords to a MITM server via an ungated clear-text auth plugin (CVE-2026-55860) and can silently corrupt data on a mid-session charset switch (CVE-2026-55859); the JDBC connector's PAM/dialog plugin inherited the same missing secure-transport gate as mysql_clear_password (CVE-2026-55857); the server discloses passwords on the initial-handshake path even under sslMode=verify-full when no certificate is pinned (CVE-2026-55856); and JDBC sends the password before its own fingerprint check completes, so a MITM captures it even though the connection is then rejected (CVE-2026-55215, rated high on its own). Same root cause as yesterday — drivers trusting server-stated auth/charset instead of enforcing their own — just more instances of it surfacing a day later. If you patched the server and one connector yesterday, confirm you got both JDBC and R2DBC too.

PrivateBin's attachment-download link reopens the stored-XSS hole its 2022 fix closed only for inline previews

PrivateBin's 2022 fix (CVE-2022-24833) sanitized the inline-preview blob for SVG attachments but never touched the download-link blob, so a text/html or image/svg attachment executes inline JavaScript in the instance's own origin — full cookie and same-origin fetch access — when a victim opens "Download attachment" in a new tab (CVE-2026-55696). It needs fileupload enabled (non-default) and a weakened CSP; the vendor-recommended default CSP still blocks it. A separate, lower-severity bug lets an unescaped REQUEST_URI break out of a JSON-LD context string via /?jsonld= for reflected JSON injection (CVE-2026-55891). If you run PrivateBin with file uploads on, confirm your CSP matches the recommended policy rather than waiting on the download-link fix.

buffa's protobuf decoder can be memory-amplification-bombed by an unauthenticated payload, and a separate lifetime bug lets safe Rust hit use-after-free

buffa's decode_unknown_field allocates heap memory in proportion to nested unknown protobuf fields with no budget, so a crafted payload under the default preserve_unknown_fields=true hits roughly 22x amplification — a 64 MiB input forcing about 1.4 GB of allocation, enough for an unauthenticated denial of service (CVE-2026-55407). Independently, and more interesting for anyone auditing buffa's internals, OwnedView::decode transmutes a borrowed slice to 'static and leaks that lifetime through Deref, so ordinary safe-Rust calling code can hold a reference past the buffer's drop and trigger a use-after-free with no unsafe block anywhere in the caller (CVE-2026-55406). Set preserve_unknown_fields=false or upgrade to 0.8.0 for the first; there's no config workaround for the second, only the upgrade.

Graylog's System Catalog endpoint returns protected database fields — including password hashes — through an entity-titles lookup

Graylog's system-catalog endpoint for entity titles returns supported entities' full database field values instead of just titles, and for user entities that includes the password hash — permission checks still apply, so you can only pull your own hash, but any admin-role account can pull every user's hash in the instance (CVE-2026-55425). It's not a live-credential leak, but a hash is enough to feed offline cracking against a weak password policy. Fixed in 7.1.4 with a field allowlist; there's no workaround, so upgrade rather than trying to filter the endpoint yourself.

Arc's cluster coordinator accepts join requests with no authentication when cluster.shared_secret is left unset

Arc only validates HMAC authentication on cluster-join requests if cluster.shared_secret is non-empty, but the secret defaults to empty and startup only hard-fails on a missing secret when file replication is enabled — so a network attacker who can reach the coordinator port on a cluster running with defaults can send a join request with attacker-controlled node identity, role, and addresses (CVE-2026-55678). Once accepted, the rogue node is marked healthy and can be selected by the cluster router for forwarded, authenticated requests. If you run Arc clustering, set cluster.shared_secret explicitly — don't assume enabling clustering alone gets you authentication.

AIIR's own signing and policy-verification gates could report success without enforcing the control — found in an internal adversarial review

AIIR flagged four of its own verification paths as fail-open rather than fail-closed: a require_signing gate that a forged or empty field could satisfy, a CI verification path that could report success regardless of the actual result, a release-policy gate that advertised limits it didn't enforce, and a signature check silently skipped for certain input categories. For a tool whose entire purpose is trustworthy verification, any consumer relying on these gates to block unsigned or non-conforming input could have been passing forged or unverified receipts as "verified" — the irony isn't lost given what this watch covers daily. Found via internal hardening review rather than external report; all four paths are fixed in 1.7.0, and if you gate a release or CI pipeline on AIIR's verification output, upgrade before trusting it again.

WsgiDAV's sample MySQL provider has a blind SQL injection — an example module, not enabled by default

WsgiDAV's bundled MySQLBrowserProvider example builds queries by string concatenation and drops the record key straight from the request URL into the WHERE clause with no escaping, so a single quote in the path breaks out for full blind SQL injection — confirmed locally with a boolean oracle and complete data extraction (CVE-2026-55509). It's shipped only as a sample and isn't enabled by default; installations that haven't explicitly activated the module aren't affected, which is why this rates medium rather than high despite the confirmed impact. If you did wire up MySQLBrowserProvider for a real read share, treat it as a demo-quality module and either patch the query construction yourself or replace it before exposing the share.