See how linuxfoundation compares to other vendors in security performance
cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of obtaining, renewing and using those certificates. From 1.18.0 until 1.19.6 and 1.20.3, Challenge resources under acme.cert-manager.io can be created directly by namespace users without admission validation tying the Challenge to an Order, owner reference, or Issuer-selected solver, allowing attacker-controlled Challenge.spec.solver values referencing a ClusterIssuer to bypass DNS01 solver selectors such as dnsZones, dnsNames, and matchLabels and cause cert-manager to use ClusterIssuer DNS credentials for attacker-selected provider settings and DNS names, including disclosure of X-Api-User and X-Api-Key headers for acme-dns. This issue is fixed in versions 1.19.6 and 1.20.3.
Spinnaker is an open source, multi-cloud continuous delivery platform. Prior to versions 2026.1.1, 2026.0.3, 2025.4.4, and 2025.3.4 on their respective release lines, Kustomize bake operations allow unsafe YAML tag processing in rosco manifests. This can lead to remote code execution on rosco pods when performing Kustomize bakes. This issue is fixed in versions 2026.1.1, 2026.0.3, 2025.4.4, and 2025.3.4.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.3 and 2.12.12, a WebSocket listener could route requests for the MQTT-over-WebSocket path into MQTT handling even when MQTT was not configured, allowing an unauthenticated client with access to the WebSocket listener to reach uninitialized MQTT state and crash the server process. This issue is fixed in versions 2.14.3 and 2.12.12.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.3 and 2.12.12, a client could be registered as the configured noauthuser through a parser path used when the first client operation was not CONNECT, bypassing user-level connection restrictions such as allowedconnectiontypes or proxyrequired that normal authentication would apply. This issue is fixed in versions 2.14.3 and 2.12.12.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.3 and 2.12.12, a client able to send account-scoped connection monitoring requests could crash the server by supplying Connz pagination Offset and Limit values that overflowed internal arithmetic before the response window was safely bounded. This issue is fixed in versions 2.14.3 and 2.12.12.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.3 and 2.12.12, an unauthenticated MQTT client could cause the server to retain large incomplete MQTT CONNECT packets before authentication completed, consuming server memory while the parser waited for the advertised MQTT packet length. This issue is fixed in versions 2.14.3 and 2.12.12.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.3 and 2.12.12, MQTT retained message delivery and QoS1+ durable replay could deliver messages whose original topics matched a subscriber configured subscribe deny rule because these delivery paths did not consistently recheck the concrete original topic before sending the MQTT PUBLISH to the subscriber. This issue is fixed in versions 2.14.3 and 2.12.12.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.3 and 2.12.12, an authenticated MQTT client could subscribe to the internal $MQTT.deliver.pubrel subject family, bypassing configured subscribe permissions and exposing MQTT QoS2 protocol metadata for sessions in the account. This issue is fixed in versions 2.14.3 and 2.12.12.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.3 and 2.12.8, message trace destination checks were applied to ordinary client connections but not consistently to messages arriving through leafnode connections, allowing a leafnode operator to send trace events to subjects that would not otherwise be permitted and to use trace-only behavior to prevent normal delivery or storage of affected messages. This issue is fixed in versions 2.14.3 and 2.12.8.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.1 and 2.12.9, an MQTT client could include protocol control characters in subscription filters that were later forwarded as NATS protocol data to route or leafnode connections, corrupting the forwarded protocol stream and allowing injection of unintended NATS protocol operations. This issue is fixed in versions 2.14.1 and 2.12.9.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.12.8 and 2.11.17, an unauthenticated peer with network access to a leafnode listener with compression enabled could crash the server during the pre-authentication leafnode handshake by sending repeated leafnode INFO protocol messages before authentication and account setup completed. This issue is fixed in versions 2.12.8 and 2.11.17.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.0, 2.12.7, and 2.11.16, an authenticated user could receive messages on denied subjects when a wildcard subscription overlapped with a configured wildcard deny rule but was not a subset of it, and queue subscriptions could also affect delivery to legitimate queue consumers. This issue is fixed in versions 2.14.0, 2.12.7, and 2.11.16.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.0, 2.12.7, and 2.11.16, when noauthuser was configured, a parser fast path intended for ordinary client connections could also apply to route or leafnode listeners, allowing an unauthenticated peer to bypass inter-server CONNECT authentication and operate with the privileges associated with that connection type. This issue is fixed in versions 2.14.0, 2.12.7, and 2.11.16.
NATS Server is a high-performance server for NATS.io, the cloud and edge native messaging system. Prior to 2.14.0, 2.12.7, and 2.11.16, an authenticated user with subscription deny permissions could bypass a plain subject deny rule by using a queue subscription, because queue-specific deny evaluation could override the plain subject deny result when the queue name itself was not denied. This issue is fixed in versions 2.14.0, 2.12.7, and 2.11.16.
Summary
Null pointer dereference (SIGSEGV) in Upsample67::adaptupsample67() (onnx/versionconverter/adapters/upsample67.h:31) when convertversion() processes a model with an Upsample node that has zero inputs. The adapter accesses node->inputs()[0]->sizes() without checking input count. 107-byte PoC crashes on Release build.
This is the same class of bug as the Cast adapter advisory (separate report) but in a different adapter, different file, and different operator.
Details
The Upsample 6→7 adapter validates attributes but not inputs: cpp // upsample67.h:20-33 void adaptupsample67(..., Node node) const { ONNXASSERTM( node->hasAttribute(widthscalesymbol) && node->hasAttribute(heightscalesymbol), "...") // Attribute check PASSES
auto widthscale = node->f(widthscalesymbol); auto heightscale = node->f(heightscalesymbol);
auto inputshape = node->inputs()[0]->sizes(); // ^^^^^^^^^^^^^^^^^^^^ // OOB when inputs().size() == 0 → SIGSEGV }
The PoC has an Upsample node at opset 6 with the required widthscale and heightscale attributes but zero inputs. The attribute assertions pass, then node->inputs()[0] on an empty ArrayRef: - Release builds (NDEBUG): bounds-check assertion compiled out → reads garbage pointer → SIGSEGV - Debug builds: assert(Index < Length) at arrayref.h:159 → SIGABRT
An Upsample node with zero inputs passes graphProtoToGraph() because the import code only resolves input names present in the protobuf.
PoC python import base64 import onnx from onnx import versionconverter
pocb64 = "CAI6YQo8EgFZIghVcHNhbXBsZSoVCgt3aWR0aF9zY2FsZRUAAABAoAEBKhYKDGhlaWdodF9zY2FsZRUAAABAoAEBEgR0ZXN0YhsKAVkSFgoUCAESEAoCCAEKAggBCgIIBAoCCARCBAoAEAY="
model = onnx.loadfromstring(base64.b64decode(pocb64))
CRASHES — Upsample67 adapter dereferences empty inputs array versionconverter.convertversion(model, 7) # SIGSEGV
107-byte PoC. Confirmed SIGSEGV on both onnx 1.21.0 (pip) and 1.22.0 (source build).
Impact
Any application that uses onnx.versionconverter.convertversion() on untrusted models is vulnerable. This includes model conversion pipelines and tools that auto-upgrade opset versions for compatibility. The crash is unrecoverable (SIGSEGV).
This vulnerability is part of a systemic pattern across multiple version converter adapters. A full audit of all ~45 adapters was performed as part of the fix; eight adapters were found with the same class of unguarded indexed access (cast98, softmax1213, softmax1312, upsample67, upsample910, groupnormalization2021, broadcastforwardcompatibility, upsample98) and all have been fixed in PR #7813.
OpenTelemetry Java Instrumentation provides OpenTelemetry auto-instrumentation and instrumentation libraries for Java. In versions prior to 2.27.0, the RMI context propagation payload reader limits the number of context entries but does not limit the aggregate size of the strings read from the stream. An attacker who can reach an RMI endpoint on an instrumented JVM can send an oversized context propagation payload. This can cause excessive memory allocation while the JVM reads the payload, potentially leading to denial of service. The issue affects only deployments where RMI instrumentation is enabled and an RMI endpoint is network-reachable. This issue has been fixed in version 2.27.0.
OpenTelemetry Java Instrumentation JDBC auto-instrumentation may fail to sanitize passwords in SQL CONNECT statements when the password is double-quoted. As a result, clear-text database passwords can be added to trace span attributes and exported to observability backends.
Impact
An unauthenticated remote attacker can trigger unbounded memory growth on the timestamp authority server.
This vulnerability exists because the global wrapMetrics middleware records the raw HTTP request path (r.URL.Path) and raw HTTP request method (r.Method) as Prometheus labels for latency and request count metric vectors. Since this middleware runs before standard routing occurs, it executes for all incoming requests, including those for unmatched paths (yielding 404 responses) or arbitrary request methods. The Prometheus library registers a new, permanent time-series entry for every distinct label combination. An attacker can continuously issue requests containing random paths (e.g., /api/v1/timestamp/<uuid>) or random HTTP methods to exhaust system memory.
Patches
This issue has been patched by limiting the metric label values to a strict allowlist of expected paths (/ping, /api/v1/timestamp, /api/v1/timestamp/certchain) and expected HTTP methods (GET, POST, HEAD, OPTIONS). Unrecognized paths or methods are normalized to a static string ("unrecognized").
Users should update to version v2.0.7 or later.
Workarounds
1. Block or drop incoming requests with invalid HTTP methods or unknown request paths at a reverse proxy or load balancer before they reach the timestamp authority server. 2. Configure rate-limiting on the public interface to prevent remote attackers from issuing millions of unique requests in a short duration.
Impact There's an unsafe YAML processing vulnerability that bypasses safe deserialization. This impacts users when when performing: CloudFormation deployments CloudFoundry Baking
The usage of a non-safe constructor use allows arbitrary loading of Java classes leading to RCE.
Patches 2025.3.3, 2026.0.3 and 2025.4.4.
Workarounds Disable the CloudFormation system and cloudfoundry baking operations.
Resources Join Spinnaker on Slack for more information!
Impact containerd's CRI checkpoint import process contains a vulnerability where it fails to validate the image references specified within a checkpoint image's configuration. An attacker with permissions to create pods can use a crafted checkpoint image to force containerd to pull a malicious image and assign it an arbitrary local tag, thereby poisoning the node's local image cache. Subsequently, if other pods on the same node attempt to use the poisoned tag with an IfNotPresent (or Never) pull policy, they will unknowingly execute the attacker's malicious image instead of the legitimate one. This can lead to a compromise of the affected pods, allowing the attacker to execute arbitrary code under the victim pod's identity.
Patches This bug has been fixed in the following containerd versions:
2.3.2 2.2.5 2.1.9
Users should update to these versions to resolve the issue. Workarounds Users should only allow trusted images to be pulled.
Credits The containerd project would like to thank Henry Beberman (@hbeberman) of Microsoft, the GKE Security Team using Gemini, Anthropic Research, in collaboration with Claude, and Robert Prast (@robertprast) who independently discovered and responsibly disclosed this issue in accordance with the containerd security policy.
For more information If you have any questions or comments about this advisory:
Open an issue in containerd Email us at security@containerd.io
To report a security issue in containerd: Report a new vulnerability Email us at security@containerd.io
Impact A bug was found in containerd where the CRI plugin propagates labels from an image config (LABEL instruction in Dockerfile) to a container without validation. This may result in executing an arbitrary command on the host, via a plugin that consumes container labels for some operations.
Patches This bug has been fixed in the following containerd versions:
2.3.2 2.2.5 2.1.9 2.0.10 1.7.33
Users should update to these versions to resolve the issue.
Workarounds Ensure that only trusted images are used.
Credits The containerd project would like to thank Anthropic Research, in collaboration with Claude, the GKE Security Team using Gemini, and Robert Prast (@robertprast) for independently discovering and responsibly disclosing this issue in accordance with the containerd security policy.
For more information
If you have any questions or comments about this advisory:
Open an issue in containerd Email us at security@containerd.io
To report a security issue in containerd: Report a new vulnerability Email us at security@containerd.io
Impact A bug was found in containerd where the CRI plugin restores container.log from a checkpoint image without validating a symlinked path. This could result in reading an arbitrary file on the host via kubectl logs.
Patches This bug has been fixed in the following containerd versions:
2.3.2 2.2.5 2.1.9
Users should update to these versions to resolve the issue.
Workarounds Ensure that only trusted images and checkpoints are used.
Credits The containerd project would like to thank @gouldnicholas and @davidrxchester, Yuming Zhang and Song Li of Zhejiang University, Sangwon Ryu (@sangwon090), Henry Beberman (@hbeberman) of Microsoft, the GKE Security Team using Gemini, Anthropic Research, in collaboration with Claude, Robert Prast (@robertprast), Kyle Elliott (@kyle-elliott-tob) of Trail of Bits, and Zhenchen Wang (@Plucky923), who independently discovered and responsibly disclosed this issue in accordance with the containerd security policy.
For more information
If you have any questions or comments about this advisory:
Open an issue in containerd Email us at security@containerd.io
To report a security issue in containerd: Report a new vulnerability Email us at security@containerd.io
Impact
containerd's CRI implementation improperly trusts Container Device Interface (CDI) annotations found within untrusted checkpoint image metadata during container restoration. When restoring a container from a checkpoint, containerd preserves CDI-related annotations from the checkpoint archive rather than relying solely on the pod's create-time specification. This allows a user with pod creation permissions to bypass standard Kubernetes resource allocation and device plugin enforcement, injecting arbitrary CDI edits (such as device nodes and host mounts) into the restored container. Successful exploitation requires that the node has CDI enabled and contains a matching host CDI specification for the requested device; environments where CDI is disabled or lacking sensitive device specifications are not affected.
Patches
This bug has been fixed in the following containerd versions:
2.3.2 2.2.5 2.1.9
Users should update to these versions to resolve the issue. Recreating existing containers restored from untrusted checkpoints may be necessary to remove smuggled configuration.
Workarounds
Users can mitigate this issue by restricting the restoration of containers from untrusted checkpoint images. If Container Device Interface (CDI) capabilities are not utilized on the node, removing or temporarily relocating host CDI specifications from the default directories (/etc/cdi and /var/run/cdi) will eliminate the reachability of this vulnerability.
Credits
The containerd project would like to thank Robert Prast (@robertprast) for responsibly disclosing this issue in accordance with the containerd security policy.
For more information
If you have any questions or comments about this advisory:
Open an issue in containerd Email us at security@containerd.io
To report a security issue in containerd: Report a new vulnerability Email us at security@containerd.io
Impact A vulnerability in containerd allows a maliciously crafted image to cause a Denial of Service (DoS) condition. When creating a container from this image, memory exhaustion occurs, leading to an Out Of Memory (OOM) kill of the containerd process. This renders the container runtime API unavailable and can disrupt clients such as the Docker Engine or Kubernetes control-plane components.
Patches This bug has been fixed in the following containerd versions:
2.3.2 2.2.5 2.1.9 2.0.10 1.7.33
Users should update to these versions to resolve the issue.
Workarounds Ensure that only trusted images are used and that only trusted users have permissions to import images or schedule pods.
Credits
The containerd project would like to thank Jakub Ciolek (@jake-ciolek) at AlphaSense and Kyle Elliott @ Trail of Bits who independently discovered and responsibly disclosed this issue in accordance with the containerd security policy.
For more information
If you have any questions or comments about this advisory:
Open an issue in containerd Email us at security@containerd.io
To report a security issue in containerd: Report a new vulnerability Email us at security@containerd.io
Impact When setting up the container rootfs, setupPtmx and setupDevSymlinks call os.Remove and os.Symlink with a filepath.Join string which allow an image with /dev as a symlink to trick runc into deleting files called ptmx on the host or creating a hardcoded set of symlinks with specific names and targets in an arbitrary pre-existing host directory.
Please note that this issue is not exploitable under Docker because it creates a top-level ro layer that masks any malicious /dev symlink present in the container image (this is also done without mounting the lower layers so there is no opportunity for the malicious /dev symlink to trick it into resolving to some other path). Unfortunately, Podman and containerd<sup>†</sup> do not do this and so users using those higher-level runtimes with runc can be exploited via a malicious image.
This issue mirrors a somewhat similar issue in crun, which was also published recently.
† Actually, at the time the issue was analysed, containerd had dead code that implemented this feature but the implementation contained several security issues that would arguably have made it more exploitable than in runc. Luckily, the code appears to have never been used (at least since 2017) and the code has since been removed.
Mitigating Factors ####
There are a few mitigating factors about this issue which reduce the impact for most users quite significantly, and is the reason why we decided to release the fix publicly without an embargo.
While the deletion of ptmx seems like a significant issue, in practice it is quite limited. Notably, devpts does not permit you to unlink /dev/pts/ptmx regardless of privileges and so it is not a usable target for this attack. Additionally, while /dev/ptmx can be unlinked<sup>‡</sup>, trying to use an image with a symlink from /dev to /dev will cause runc will return an error before it reaches the buggy code (it correctly detects a symlink loop while setting up the mount target and the code correctly scopes the lookup inside the container). Thus, the only files called ptmx that are guaranteed to exist on the system cannot actually be removed by this bug and so only some user file that happens to have that specific name could be deleted, which seems fairly unlikely to happen on real systems.
As for the issue of symlinks, again the impact is likely quite limited. While the creation of arbitrary symlinks could be used to create drop-in files for system services (and thus lead to a container breakout), the hardcoded set of symlink names and targets that this bug allows you to create on the host make it quite unlikely that you would be able to do much more than pollute the host system with dummy symlinks. Here is the complete list of symlinks that can be created with this attack:
core → /proc/kcore fd → /proc/self/fd/ ptmx → pts/ptmx stdin → /proc/self/fd/0 stdout → /proc/self/fd/1 stderr → /proc/self/fd/2
Note that none of these symlinks are likely to point to user-controlled data -- the /proc/self/fd/$n symlinks are all properties of the process accessing them (so privileged processes will only see the state they were spawned with) and the pts/ptmx symlink is almost certainly in the same privilege scope as the directory the symlink itself is in. It seems the only somewhat plausible impact would be that a service could return an error when trying to parse one of these symlinks and thus treat it as an invalid configuration file. How arbitrary processes deal with this situation is a bit hard to analyse, but most daemons require configuration files to have certain suffixes (such as .conf) so it's not really clear how large the impact is in practice and it seems there are a few barriers to clear to use this to cause a DoS or other problems.
‡ This would actually be quite problematic if it could occur because glibc seemingly only attempts to use /dev/ptmx when creating new terminals and thus most terminal managers (including tmux) and shell tools (including sudo -- but not su) would fail to start and thus bring the system to a halt. setupPtmx does add a symlink to /dev/pts/ptmx afterwards but on some systems the mode of the host /dev/pts/ptmx is set to 0o000 which would still cause the same DoS issue.
Patches This issue has been patched in runc 1.3.6, runc 1.4.3, and runc 1.5.0-rc.3.
Workarounds Using user namespaces restricts this attack fairly significantly such that the attacker can only create/delete inodes in directories that the remapped root user/group has write access to. Unless the root user is remapped to an actual user on the host (such as with rootless containers that don't use /etc/sub[ug]id), this in practice means that an attacker would only be able to create or delete inodes in world-writable directories.
LSMs can restrict the scope of where in the host filesystem runc can be tricked into operating on, though how much this helps is questionable. The default containerruntimet SELinux label rules (or custom AppArmor rules for the host runc context) may restrict the scope where these filesystem operations can operate on, but we have not done an in-depth analysis on the impact of those kinds of LSM protections.
Resources commit opencontainers/runc@864db8042dbb ("rootfs: make /dev initialisation code fd-based") https://github.com/containers/crun/security/advisories/GHSA-7vwr-4279-7gq5
Credits runc thanks "Davias" for initially finding and reporting this issue. The same underlying issue (with varying levels of completeness) was later reported by Arthur Chan (@arthurscchan from Ada Logics), Junyi Liu (@mosskappa), and Derek Manzella (@Dmanzella).
A vulnerability in Kedro version 1.2.0 allows an attacker to exploit path traversal by providing a crafted version string. The getversionedpath() method in kedro/io/core.py directly interpolates user-supplied version strings into filesystem paths without sanitization. This enables an attacker to escape the intended versioned dataset directory and access files outside the expected path. The issue is also reachable through the CLI via the --load-versions parameter, as splitloadversions() in kedro/framework/cli/utils.py does not validate the version string. This vulnerability can lead to unauthorized file reads, data poisoning, cross-project or cross-tenant data access, and broader downstream impacts in environments where Kedro is used with automation or orchestration layers.
Impact A bug was found in containerd where containers launched with a numeric User directive that cannot be parsed as a 32-bit integer are incorrectly treated as a username. If a crafted image provides an /etc/passwd file mapping this large numeric string to root, the container ultimately runs as root (UID 0). This allows the Kubernetes runAsNonRoot restriction to be bypassed, causing unexpected behavior for environments that require containers to run as a non-root user.
Patches This bug has been fixed in the following containerd versions:
2.3.1 2.2.4 2.0.9 1.7.32
Note: The containerd 2.1 release has reached its end of life and a fixed version is not provided.
Users should update to these versions to resolve the issue.
Workarounds Ensure that only trusted images are used and that only trusted users have permissions to import images. Alternatively, enforcing a specific numeric runAsUser in the Kubernetes Pod securityContext overrides the USER directive in the image and prevents the bypass. Newer versions of Kubernetes, starting with 1.34, also appear to enforce runAsNonRoot properly regardless of this bug.
Credits The containerd project would like to thank Lei Wang (@ssst0n3) for responsibly disclosing this issue in accordance with the containerd security policy.
Resources https://github.com/advisories/GHSA-265r-hfxg-fhmg (CVE-2024-40635)
For more information
If there are any questions or comments about this advisory:
Open an issue in containerd Send an email to security@containerd.io
To report a security issue in containerd: Report a new vulnerability Send an email to security@containerd.io
Summary
On 2026-05-11, between approximately 19:20 and 19:26 UTC, 84 malicious versions across 42 @tanstack/ packages were published to the npm registry. The publishes were authenticated via the legitimate GitHub Actions OIDC trusted-publisher binding for TanStack/router, but the publish workflow itself was not modified. The attacker chained three known vulnerability classes — a pullrequesttarget "Pwn Request" misconfiguration, GitHub Actions cache poisoning across the fork↔base trust boundary, and runtime memory extraction of the OIDC token from the Actions runner process — to publish credential-stealing malware under a trusted identity.
Each affected package received exactly two malicious versions, published a few minutes apart.
Impact
A user installing any affected version executes a payload (~2.3 MB obfuscated routerinit.js) at install time that:
- Harvests credentials from common locations: - AWS instance metadata (IMDS) and Secrets Manager - GCP metadata service - Kubernetes service-account tokens - HashiCorp Vault tokens - ~/.npmrc (npm tokens) - GitHub tokens (env vars, gh CLI config, .git-credentials) - SSH private keys (~/.ssh/) - Exfiltrates harvested data over the Session/Oxen messenger file-upload network (filev2.getsession.org, seed{1,2,3}.getsession.org). This is end-to-end encrypted with no attacker-controlled C2, so blocking by IP or domain is the only network mitigation. - Enumerates packages that the victim maintains via registry.npmjs.org/-/v1/search?text=maintainer:<user> and republishes them with the same injection, propagating the compromise across npm.
Any developer or CI environment that ran npm install, pnpm install, or yarn install against an affected version on 2026-05-11 should be considered compromised. All credentials accessible to the install process should be rotated immediately. Cloud audit logs should be reviewed for activity originating from the affected hosts during and after the install window.
Detection
Inspect the published manifest of any pinned @tanstack/ version. Malicious manifests contain this exact optionalDependencies entry:
json "optionalDependencies": { "@tanstack/setup": "github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c" }
To check a version without running install scripts:
bash npm pack @tanstack/<name>@<version> # downloads tarball; does NOT execute lifecycle scripts tar -xzf .tgz grep -A3 optionalDependencies package/package.json ls -la package/routerinit.js # malicious payload, ~2.3 MB, present at package root
The payload file routerinit.js is approximately 2.3 MB of obfuscated JavaScript. It is placed at the tarball root and is intentionally not declared in the package's "files" array, so it does not appear in the package's documented contents.
Mechanism
@tanstack/setup is not a real package on the npm registry. The github:tanstack/router#79ac49ee... specifier resolves to an orphan commit pushed to a fork in the tanstack/router GitHub fork network. GitHub serves commits across the entire fork network for git-URL dependencies, so the attacker did not require write access to TanStack/router itself — only the ability to fork and push to their own fork.
When npm processes the optional dependency, it:
1. Fetches the orphan commit from the fork network. 2. Installs the commit's declared dependencies (which include a real bun binary). 3. Runs the commit's prepare lifecycle script: bun run tanstackrunner.js && exit 1. The trailing exit 1 causes the optional install to fail, after which npm silently discards it — leaving no nodemodules trace. 4. The tanstackrunner.js script in turn executes routerinit.js from the host package's tarball.
Patches
Affected versions are being deprecated on npm with a SECURITY: notice. Where npm policy allows (no existing third-party dependents), affected versions are also being unpublished. The npm security team has been engaged to pull tarballs server-side for versions that cannot be unpublished.
Clean follow-up releases are being prepared. Update to the patched version listed in the affected-products table for each package, then reinstall from a clean lockfile.
Workarounds
Until clean follow-up releases are available:
- Pin every @tanstack/ dependency to a known-good version published before 2026-05-11 19:00 UTC. The last known-good version for most affected packages was published on 2026-03-15. - Delete nodemodules and the lockfile, then reinstall to ensure no transitive dependency resolves to a malicious version. - Configure npm to skip lifecycle scripts on install (npm config set ignore-scripts true) as a temporary defense-in-depth measure. - For CI, audit any pipeline that ran install against @tanstack/ between 19:20 and 19:30 UTC on 2026-05-11. Treat the runner as compromised and rotate any secrets it had access to.
Indicators of compromise
| Indicator | Value | |---|---| | Malicious git ref | github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c | | Fictitious package name | @tanstack/setup | | Payload filename | routerinit.js (~2.3 MB, package root, undeclared in files) | | Helper filename in orphan commit | tanstackrunner.js | | Exfiltration network | filev2.getsession.org, seed1.getsession.org, seed2.getsession.org, seed3.getsession.org | | Second-stage payload URLs | https://litter.catbox.moe/h8nc9u.js, https://litter.catbox.moe/7rrc6l.mjs | | Poisoned cache key | Linux-pnpm-store-6f9233a50def742c09fde54f56553d6b449a535adf87d4083690539f49ae4da11 | | Publish window (UTC) | 2026-05-11 19:20 — 19:26 | | Publish mechanism | GitHub Actions OIDC trusted publisher (oidc:db7d6f54-05d5-412b-8a10-e7a8398b303e) | | Workflow runs | https://github.com/TanStack/router/actions/runs/25613093674 (attempt 4), https://github.com/TanStack/router/actions/runs/25691781302 | | Attacker GitHub accounts | zblgg (id 127806521), voicproducoes (id 269549300) | | Attacker fork (renamed to evade detection) | https://github.com/zblgg/configuration |
Credits
- The security researcher who initially disclosed the vulnerability publicly with detailed analysis at https://github.com/TanStack/router/issues/7383
References
- Public incident tracking issue: https://github.com/TanStack/router/issues/7383 - Related research: - Adnan Khan, "The Monsters in Your Build Cache: GitHub Actions Cache Poisoning" (May 2024) - GitHub Security Lab, "Keeping your GitHub Actions and workflows secure: Preventing Pwn Requests" - StepSecurity, "tj-actions/changed-files action is compromised" (March 2025) — the malicious payload reuses this incident's runner-memory extraction technique verbatim
Impact
The CloudNativePG metrics exporter opens its PostgreSQL connection as the postgres superuser via the pod-local Unix socket, then demotes the session with SET ROLE pgmonitor. SET ROLE changes only currentuser; sessionuser remains postgres. That residual superuser identity is the foothold for the rest of the chain.
Any SQL expression evaluated inside the scrape session can invoke RESET ROLE to recover real superuser privileges, then use COPY ... TO PROGRAM to spawn an OS-level subprocess as the postgres user inside the primary pod. The READ ONLY transaction flag does not block this; it gates writes to database state, not external processes.
Two exploitation paths follow from this root cause.
Path 1: custom metric queries with unqualified identifiers (all supported releases)
A database user who owns a schema on the searchpath of any scraped database can plant a shadow object whose name matches an unqualified identifier in a custom metric query. When the exporter next evaluates that query, the shadow expression executes inside the sessionuser = postgres scrape session, giving the attacker PostgreSQL superuser privileges and OS command execution inside the primary pod within one scrape interval (≤30 s). Exploitability requires a custom metric query that contains an unqualified relation or function reference.
Although searchpath shadowing of unqualified identifiers is the most direct case, the underlying bug is that any expression evaluated inside the scrape session is a superuser code path. Other exploitable shapes include user-defined functions, operators or casts resolved during the scrape, joins or subqueries against user-owned tables and views, and index expressions or RLS policies on read-touched objects.
Path 2: stock default-monitoring.yaml (all supported releases, no custom metrics required)
The pgextensions metric shipped in default-monitoring.yaml used an unqualified currentdatabase() call and ran against every user database (targetdatabases: ''). Any non-superuser who owns a user database (including the default app role created by bootstrap.initdb) could shadow currentdatabase() and trigger the full escalation chain against a stock CNPG deployment on the first scrape after the shadow was planted.
Combined impact
The chain yields privilege escalation from a low-privileged database role (e.g. the default app role) to PostgreSQL superuser, plus arbitrary OS command execution as the postgres user inside the primary pod, all within one scrape interval. A web application SQL injection vulnerability in an app backed by a CNPG cluster is therefore sufficient to pivot to database-pod RCE.
Who is impacted
- All deployments on any supported release with default monitoring enabled are affected by Path 2. - All deployments on any supported release that use custom metric queries containing unqualified catalog references are affected by Path 1. - Multi-tenant platforms that allow customers to supply or influence custom metric query bodies are at the highest risk for Path 1.
Patches
Three separate patches address the vulnerability.
Patch 1: PR #10576 "schema-qualify catalog references in default monitoring queries and documentation samples"
Schema-qualifies all unqualified pgcatalog function and view references in the shipped default-monitoring.yaml and in documentation examples. This closes Path 2 in operator-shipped configuration and removes the unqualified-identifier attack surface from all operator-shipped metric queries. Operators who clone or copy default-monitoring.yaml into custom monitoring ConfigMaps, or have copy-pasted unqualified queries elsewhere, must re-qualify those queries themselves.
Backported to all currently supported releases:
- v1.29.x (x ≥ 1) - v1.28.x (x ≥ 3)
Patch 2: "dedicated cnpgmetricsexporter role with pgident.conf peer mapping"
Introduces a dedicated cnpgmetricsexporter PostgreSQL role (granted pgmonitor, no superuser privileges) and maps it in pgident.conf via peer authentication on the local Unix socket, following the same pattern already used for cnpgpoolerpgbouncer. The metrics exporter connects as this role instead of postgres, so sessionuser is never a superuser and RESET ROLE has no escalation effect. This eliminates the root cause entirely.
Demoting the session at the SQL level (via SET SESSION AUTHORIZATION pgmonitor) is not sufficient: the privilege check for SET SESSION AUTHORIZATION is whether the authenticated user is a superuser, not the current sessionuser. With the connection still authenticated as postgres, any SQL in the session can run RESET SESSION AUTHORIZATION and recover the original superuser identity. This is the same recovery primitive as RESET ROLE, one layer up. Only changing the authenticated user closes the loop.
With this change in place, the original chain breaks at every step: RESET ROLE and RESET SESSION AUTHORIZATION cannot recover superuser, and COPY ... TO PROGRAM requires a privilege pgmonitor does not grant. As defense in depth, the monitoring transaction also prepends pgcatalog to the connection's searchpath, so unqualified catalog identifiers cannot resolve to user-planted shadow objects.
This patch changes the connection identity but not how queries are evaluated. Custom metric queries within pgmonitor's scope (catalog reads, pgstat views, settings) continue to work without modification. Queries that previously relied on superuser-level access (reading user-owned tables not granted to cnpgmetricsexporter, or superuser-only catalogs such as pgauthid or pgsubscription) will fail and need explicit GRANT statements to cnpgmetricsexporter.
The role is created and maintained with PASSWORD NULL; any password set out-of-band is cleared on the next reconcile, so the role cannot be authenticated by password regardless of operator pre-creation.
For replica clusters, upgrade the source primary cluster before any replica clusters that consume from it. The cnpgmetricsexporter role is created on the source primary and replicates downstream; a replica cluster upgraded first will scrape against a missing role until the source primary upgrades or the role is created manually (see the monitoring documentation).
The patch will be backported to all currently supported releases:
- v1.29.x (x ≥ 1) - v1.28.x (x ≥ 3)
Workarounds
If upgrading immediately is not possible:
1. Schema-qualify all identifiers in custom metric queries. Use explicit pgcatalog. prefixes for all catalog functions and views (e.g. pgcatalog.currentdatabase(), pgcatalog.now()). This is a partial mitigation: it closes the searchpath-shadowing shape in operator- and user-supplied metric bodies, but other expression shapes (user-defined functions, operators or casts; joins or subqueries on user-owned tables and views; RLS policies on read-touched objects) remain superuser code paths until Patch 2 lands.
2. Restrict database ownership. Ensure only fully trusted roles own user databases in scraped clusters. The exploit requires the ability to plant an object on the metrics exporter's searchpath in a scraped database, typically by owning the database (and therefore public via pgdatabaseowner) or by holding CREATE on a schema already reachable through searchpath.
PG <15 caveat: public grants CREATE to PUBLIC by default before PostgreSQL 15, so any authenticated role in a scraped database can plant a shadow object regardless of ownership.
3. Limit the scope of targetdatabases: '' queries. Avoid targetdatabases: '' unless every database in the cluster, and every role that owns one, is fully trusted. Where possible, restrict targetdatabases to specific, known-safe databases.
4. Do not expose metric query SQL to untrusted users. Multi-tenant platforms that allow customers to supply or influence custom metric query bodies should treat this as a critical trust boundary until the architectural fix is released.
References
- Fix (Patch 1): PR #10576 "schema-qualify catalog references in default monitoring queries and documentation samples" - Fix (Patch 2): "dedicated cnpgmetricsexporter role with pgident.conf peer mapping" - Reported by: Mehmet Ince
Impact The Volcano webhook server does not enforce a size limit on incoming HTTP request bodies. Any in-cluster pod that can reach the webhook endpoint may send an arbitrarily large request body, potentially causing the webhook server to be killed by OOM. All Volcano deployments with the webhook server exposed to in-cluster traffic are affected.
Patches This issue will be fixed in the following versions: - v1.14.2 - v1.13.3 - v1.12.4
Users running versions below these should upgrade accordingly.
Workarounds No known workarounds. Upgrade to the patched versions listed above.