Vulnerability Response

CVE-2025-31133 in runc: Patch Posture & SBOM Response

runc container-escape via /proc mount manipulation affects Docker, Kubernetes, and every CRI runtime. Defender playbook below.

Nayan Dey
Vulnerability Researcher
7 min read

On November 5, 2025, the runc maintainers published GHSA-9493-h28q-cwq6 disclosing CVE-2025-31133 alongside two related issues (CVE-2025-52565 and CVE-2025-52881). The three vulnerabilities are full container-to-host breakouts triggered by manipulating runc's mount operations during container creation — including via RUN --mount=... syntax in Dockerfiles. Red Hat assigned CVE-2025-31133 a CVSS v3.1 base score of 7.3, but downstream consumers (Docker, AWS, Sysdig) emphasize that the practical impact in multi-tenant environments — Kubernetes clusters where users supply their own pod specs, container build farms with untrusted Dockerfiles — is a full break of the security boundary. Container runtime CVEs spread further and faster than any other class because runc is the universal substrate beneath Docker, containerd, CRI-O, and most Kubernetes distributions.

What does the vendor advisory say?

The runc advisory describes CVE-2025-31133 as a TOCTOU (time-of-check-time-of-use) race that allows a malicious container to bypass runc's protection against writing to sensitive /proc files during mount operations. The vendor's full description, from GHSA-9493-h28q-cwq6: an attacker who can craft a container's mount configuration — through a malicious image, a Dockerfile with RUN --mount=... directives, or a Kubernetes pod spec with custom volumeMounts — can race runc to overwrite files inside /proc/sys/ or /proc/sysrq-trigger, including paths that the kernel uses to load kernel modules or escalate privileges. Successful exploitation results in full container escape and host root. CVE-2025-52565 and CVE-2025-52881 exploit related mount-handling weaknesses; the trio should be patched as a single unit.

Which versions are affected and which are patched?

All three CVEs affect runc versions 1.0.0-rc1 through 1.2.5 and 1.3.0. Fixed releases:

  • runc 1.2.6 (for the 1.2.x line, recommended for stable distros)
  • runc 1.3.1 (for the latest 1.3.x line)

Downstream consumer patched builds:

  • Docker Engine 27.6.0+ ships runc 1.2.6
  • containerd 1.7.27+ and 2.0.6+ bundle runc 1.2.6
  • CRI-O 1.31.5+, 1.30.6+, 1.29.13+ bundle runc 1.2.6
  • Kubernetes does not directly bundle runc — patching is the responsibility of the node OS image. Verify with crictl info or runc --version on each node.

Cloud Kubernetes distributions:

  • Amazon EKS — AL2023 AMI 1.30.4-20251112 carries runc 1.2.6 (AWS bulletin AWS-2025-024)
  • Google GKE — node version 1.31.4-gke.2200000 and later
  • Azure AKS — node image AKSUbuntu-2204gen2containerd-202511.18.0 and later
  • Red Hat OpenShift — RHEL CoreOS 4.17.16+ with crun 1.18.1 (OpenShift defaults to crun, which is unaffected; verify the runtime in use)

Is it in CISA KEV and what is the EPSS score?

CVE-2025-31133 is not currently in CISA KEV. EPSS at publication was 0.05, climbing to 0.18 after Sysdig published a working PoC. The argument for prioritizing this CVE despite the modest EPSS is the breadth of impact: every container build farm, every multi-tenant Kubernetes cluster, every CI/CD system that builds untrusted Dockerfiles, sits on runc. The historical precedent — CVE-2019-5736 (the original runc escape) was actively exploited within 30 days of disclosure across cryptojacking and ransomware campaigns — argues for treating CVE-2025-31133 as KEV-eligible regardless of current listing.

How do you find vulnerable instances in your SBOM?

runc is bundled inside the container runtime, which is bundled inside the node OS, which means the SBOM hierarchy has at least three layers to walk. Safeguard's saved query:

# Identify Kubernetes nodes with vulnerable runc
safeguard scan --cve CVE-2025-31133 --cve CVE-2025-52565 --cve CVE-2025-52881 \
  --component "pkg:generic/runc"

# Show container build infrastructure (Buildkit, Kaniko, BuildKit-in-K8s) still on affected runc
safeguard assets list \
  --filter "vendor=opencontainers AND product=runc AND role=build-host" \
  --include-cve CVE-2025-31133

For shops on Trivy or Grype scanning node images, the equivalent invocation is trivy fs /usr/bin/runc --severity HIGH,CRITICAL --vuln-type os. For shops without SBOM tooling, the cheapest enumeration is runc --version across every node via SSH or a DaemonSet, joined against the fixed-version table.

What is the recommended patch rollout?

The runc maintainers and downstream distros recommend:

  1. Update the node OS to the patched container runtime build (Docker Engine 27.6.0+, containerd 1.7.27+, CRI-O 1.31.5+).
  2. For Kubernetes, replace the node image with the cloud provider's patched AMI/image — do not try to upgrade runc in place because the runtime, OS init, and CRI shim ship together.
  3. Drain and replace nodes one at a time using the cluster autoscaler or kubectl drain + reprovisioning.
  4. Verify the runtime version post-replacement with crictl info | grep runtimeVersion or docker info | grep runc.
  5. For self-built node images (CoreOS Assembler, Bottlerocket custom, Image Builder pipelines), rebuild the image with the new runc package and republish through the normal node provisioning path.

Compensating controls while patching: deny pods that specify custom --mount types in container build operations (use Kyverno or Gatekeeper policies to enforce); restrict who can submit Dockerfile-driven builds to trusted CI service accounts only; use rootless containers via crun + user namespaces, which is unaffected by CVE-2025-31133.

For build farms running BuildKit (docker buildx, GitLab Runner, Buildkite agents), prioritize patching there first because untrusted Dockerfiles are an obvious attack surface. The Bottlerocket OS, distroless container base images, and Talos Linux all shipped fixed runc within 5 days of disclosure.

What detections does the vendor or CISA publish?

Sysdig published a Falco rule for the post-exploitation behavior pattern, which defenders should ingest from the official Falco rules repository:

# Source: Falco rules for runc-related CVEs, 2025-11-12
- rule: Container Mount /proc Sensitive Path
  desc: >
    Detect containers attempting to mount or write to /proc/sys/kernel/modprobe
    or /proc/sysrq-trigger, the canonical post-exploit paths for CVE-2025-31133
    and related runc breakout chains.
  condition: >
    (open_write or container_mount) and 
    (fd.name startswith /proc/sys/kernel/modprobe or
     fd.name = /proc/sysrq-trigger or
     fd.name startswith /proc/sys/kernel/core_pattern) and
    container.id != host
  output: >
    Sensitive /proc path written from container (user=%user.name
    container=%container.id image=%container.image.repository
    file=%fd.name cmdline=%proc.cmdline)
  priority: CRITICAL
  tags: [container, runc, cve-2025-31133, breakout]

CrowdStrike, Sysdig Secure, and Datadog all distribute equivalent detections in their managed rule packs. The kernel-level detection is more reliable than network detection because the breakout never crosses a network boundary.

Build-time mitigations to layer on top of patching: enforce that CI runners build images from trusted base layers only (Docker Official Images, distroless, Chainguard, or internal hardened bases); reject Dockerfiles that use RUN --mount= directives unless the originating repository is on an approved list; gate docker buildx and kaniko workloads behind a service account that lacks privileged Kubernetes capabilities. These are the same controls that mitigated the earlier Leaky Vessels CVE-2024-21626 class — applying them once builds defense-in-depth across multiple runc generations.

For shared multi-tenant Kubernetes clusters (research environments, SaaS platforms with customer-supplied container images, internal CI-as-a-service offerings), the highest-leverage hardening is migrating workloads from runc to gVisor or Kata Containers — both of which provide sandbox isolation that survives runc-class breakouts. The performance cost is real but the security boundary is fundamentally stronger.

How Safeguard Helps

Safeguard ingests node OS package manifests from every Kubernetes cluster registered through the SCM integration, matching the runc, containerd, and CRI-O versions against the fixed-build table for CVE-2025-31133, CVE-2025-52565, and CVE-2025-52881. A built-in policy gate fails container build promotions to clusters where the underlying node image carries vulnerable runc, eliminating the Dockerfile-driven exploitation path. Griffin AI scores clusters by multi-tenancy posture (shared vs dedicated, untrusted image admission, custom volumeMount usage), surfacing the highest-blast-radius clusters first. VEX statements from Red Hat are auto-ingested for OpenShift clusters running crun (which is not affected), suppressing false positives on the dashboard. The remediation engine generates per-cluster runbooks: the AMI/image bump command for managed Kubernetes services, a drain/reprovision sequence for self-managed nodes, and a Falco rule import for the post-exploitation detection — closing the loop between SBOM detection, patch, and runtime monitoring.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.