Skip to content

CVE-2026-50195: Verified Repro With Script Download

CVE-2026-50195: containerd CRI checkpoint import RCE

CVE-2026-50195 is verified against the affected target. Vulnerability class: RCE. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00248.

REPRO-2026-00248 RCE Variant found Jul 6, 2026 CVE entry ↗ .txt
Severity
CRITICAL
CVSS
9.9
Confidence
HIGH
Reproduced in
39m 23s
Tool calls
315
Spend
$10.44
01 · Overview

What Is CVE-2026-50195?

CVE-2026-50195 is a critical containerd vulnerability (CWE-345, insufficient verification of data authenticity) in the CRI checkpoint import path. Trusting attacker-supplied checkpoint metadata lets an attacker poison a node's local image cache and achieve remote code execution on the host. Pruva reproduced it (reproduction REPRO-2026-00248).

02 · Severity & CVSS

CVE-2026-50195 Severity & CVSS Score

CVE-2026-50195 is rated critical severity, with a CVSS base score of 9.9 out of 10.

CRITICAL threat level
9.9 / 10 CVSS base
Weakness CWE-345 (Insufficient Verification of Data Authenticity)

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

How to Reproduce CVE-2026-50195

$ pruva-verify REPRO-2026-00248
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00248/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-50195

Remote code execution — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

checkpoint archive config.dump rootfsImageRef=localhost:5000/attacker:latest and rootfsImageName=localhost:5000/victim:stable

Attack chain
  1. CRI CreateContainer checkpoint import followed by CRI CreateContainer/StartContainer for poisoned victim image tag
Runnable proof: reproduction_steps.sh
Captured evidence: vulnerable v222 exploit stdoutvulnerable v222 containerdfixed v225 exploit stdoutfixed v225 containerd
Variants tested

Digest-form config.dump rootfsImageRef (NAME@DIGEST) is an alternate trigger for the same CRI checkpoint tag-poisoning sink on vulnerable containerd v2.2.2, but it is not a bypass because fixed v2.2.5 does not create the attacker-selected rootfsImageName local tag.

How the agent worked 674 events · 315 tool calls · 39 min
39 minDuration
315Tool calls
142Reasoning steps
674Events
Agent activity over 39 min
Support
18
Hypothesis
2
Repro
474
Judge
46
Variant
129
0:0039:23

Root Cause and Exploit Chain for CVE-2026-50195

Versions: containerd versions before the patched releases 2.3.2, 2.2.5, and 2.1.9. The runtime proof uses vulnerable v2.2.2 and fixed negative control v2.2.5.

CVE-2026-50195 is a containerd CRI checkpoint import vulnerability in which metadata inside an attacker-supplied checkpoint archive is trusted during CreateContainer. In vulnerable containerd v2.2.2, the checkpoint config.dump fields rootfsImageRef and rootfsImageName are used to pull an attacker-controlled image and then create an arbitrary local image tag for it. The reproduction proves the real CRI path by importing a malicious checkpoint archive through the containerd CRI gRPC socket, poisoning localhost:5000/victim:stable so it points to localhost:5000/attacker:latest, and then creating and starting a normal victim container from the poisoned tag. The victim container runs the attacker image command and prints PRUVA_CODE_EXEC_FROM_ATTACKER_IMAGE uid=0 gid=0 image=attacker.

  • Package/component affected: github.com/containerd/containerd/v2, specifically the CRI plugin's checkpoint import path in internal/cri/server/container_checkpoint_linux.go reached from CreateContainer.
  • Affected versions: containerd versions before the patched releases 2.3.2, 2.2.5, and 2.1.9. The runtime proof uses vulnerable v2.2.2 and fixed negative control v2.2.5.
  • Risk level and consequences: Critical. An attacker who can submit a crafted CRI checkpoint image/archive can poison a node's local image cache by forcing an arbitrary local tag to resolve to attacker-controlled image content. A subsequent pod/container using that local tag with an already-present/no-pull workflow can execute attacker-controlled code under the victim container identity.

Impact Parity

  • Disclosed/claimed maximum impact: Code execution via CRI checkpoint import API by causing the host to pull and run an attacker image.
  • Reproduced impact from this run: Code execution. The vulnerable run used the real CRI endpoint to import the crafted checkpoint, created the poisoned victim:stable tag, then successfully invoked StartContainer for a normal victim container. The victim container executed the attacker image command and produced the marker PRUVA_CODE_EXEC_FROM_ATTACKER_IMAGE uid=0 gid=0 image=attacker.
  • Parity: full.
  • Not demonstrated: The proof runs in an isolated privileged Docker runner rather than a full Kubernetes cluster/kubelet. It nevertheless exercises the production containerd CRI gRPC service and CRI container lifecycle (runp, create, start) with official containerd release binaries.

Root Cause

The vulnerable checkpoint import implementation reads untrusted checkpoint metadata from config.dump and uses it as authoritative image identity. In v2.2.2, CRImportCheckpoint does the following:

  1. Reads config.RootfsImageRef from the checkpoint metadata.
  2. Calls c.client.GetImage(ctx, config.RootfsImageRef) and, if missing, c.client.Pull(ctx, config.RootfsImageRef), which pulls the attacker-selected image reference.
  3. Parses config.RootfsImageName as a valid tag.
  4. Reads the pulled image service record for config.RootfsImageRef, rewrites tagImage.Name = config.RootfsImageName, and calls c.client.ImageService().Create(ctx, tagImage).

That final tag creation step lets the checkpoint archive bind attacker image content to an arbitrary local tag. The fixed v2.2.5 code removes the vulnerable retagging block; in the negative control, the attacker image is still pulled for the checkpoint restore path, but the arbitrary victim:stable local tag is not created, so the later victim CreateContainer fails with not found instead of running attacker code.

The script records source evidence in bundle/logs/source/patch_check.txt, including the vulnerable v2.2.2 tag creation block and the fixed v2.2.5 corresponding block where it is absent.

Reproduction Steps

  1. Run bundle/repro/reproduction_steps.sh from the bundle root (the script is self-contained and uses PRUVA_ROOT if set).
  2. The script:
    • Starts a local Docker registry and builds/pushes three images: pause, a legitimate victim:stable, and an attacker image whose CMD prints PRUVA_CODE_EXEC_FROM_ATTACKER_IMAGE.
    • Downloads official containerd v2.2.2 and v2.2.5 release binaries, plus runc and crictl.
    • Builds two privileged runner containers that run real containerd CRI services.
    • For v2.2.2, creates a pod sandbox, imports a malicious checkpoint archive through crictl create where rootfsImageRef=localhost:5000/attacker:latest and rootfsImageName=localhost:5000/victim:stable, then creates and starts a normal victim container from victim:stable.
    • For v2.2.5, repeats the same flow as a fixed negative control.
  3. Expected evidence:
    • Vulnerable run: POST-CHECKPOINT: poisoned victim tag entries = 1, StartContainer rc=0, and victim logs contain PRUVA_CODE_EXEC_FROM_ATTACKER_IMAGE uid=0 gid=0 image=attacker.
    • Fixed run: POST-CHECKPOINT: poisoned victim tag entries = 0, victim CreateContainer fails with failed to resolve image "localhost:5000/victim:stable": not found, and no attacker marker appears.

Evidence

Primary proof artifacts:

  • bundle/logs/exploit_evidence.txt — concise vulnerable/fixed verdict summary.
  • bundle/logs/vulnerable_v222_exploit_evidence.txt — full vulnerable CRI flow and code execution marker.
  • bundle/logs/fixed_v225_exploit_evidence.txt — fixed negative control.
  • bundle/logs/vulnerable_v222_containerd.log and bundle/logs/fixed_v225_containerd.log — containerd service logs.
  • bundle/logs/vulnerable_v222_ctr_images.txt and bundle/logs/fixed_v225_ctr_images.txt — image store evidence.
  • bundle/repro/runtime_manifest.json — runtime manifest with entrypoint_kind=api_remote, service/health/target true, and artifact list.

Key excerpts from the successful vulnerable run:

containerd: containerd github.com/containerd/containerd/v2 v2.2.2 301b2dac98f15c27117da5c8af12118a041a31d9
checkpoint config.dump: {"rootfsImageRef":"localhost:5000/attacker:latest","rootfsImageName":"localhost:5000/victim:stable", ...}
POST-CHECKPOINT: attacker image entries = 1
POST-CHECKPOINT: poisoned victim tag entries = 1
localhost:5000/attacker:latest ... sha256:25ff2e0f0b209d91423507e05f4a369614a1014f46b6bceea502fd24fe7d289f
localhost:5000/victim:stable   ... sha256:25ff2e0f0b209d91423507e05f4a369614a1014f46b6bceea502fd24fe7d289f
StartContainer rc=0
PRUVA_CODE_EXEC_FROM_ATTACKER_IMAGE uid=0 gid=0 image=attacker
VERDICT: VULN_CODE_EXEC_CONFIRMED

Key excerpts from the fixed negative control:

containerd: containerd github.com/containerd/containerd/v2 v2.2.5 e53c7c1516c3b2bff98eb76f1f4117477e6f4e66
POST-CHECKPOINT: attacker image entries = 1
POST-CHECKPOINT: poisoned victim tag entries = 0
creating container: rpc error: code = NotFound desc = failed to check if this is a checkpoint image: failed to resolve image "localhost:5000/victim:stable": not found
VERDICT: FIXED_BLOCKED - fixed containerd did not create the victim tag and no attacker code executed

Environment details captured:

  • Official containerd v2.2.2 and v2.2.5 Linux amd64 release binaries are downloaded by the script.
  • crictl drives the real CRI gRPC endpoint at /run/containerd/containerd.sock inside the privileged runner.
  • The runtime manifest confirms service_started=true, healthcheck_passed=true, and target_path_reached=true.

Recommendations / Next Steps

  • Upgrade containerd to one of the patched versions: 2.3.2 or later, 2.2.5 or later on the 2.2 branch, or 2.1.9 or later on the 2.1 branch.
  • Preserve the fixed behavior that prevents checkpoint metadata from creating arbitrary local image tags for pulled base images.
  • Add regression tests around CRI checkpoint import where rootfsImageRef and rootfsImageName intentionally differ. The expected result should be that checkpoint import does not create or overwrite the arbitrary local tag, and a later normal container using that tag cannot resolve to attacker content.
  • Consider additional validation of checkpoint metadata provenance and consistency between image name/reference fields before any pull or restore action.

Additional Notes

  • The final bundle/repro/reproduction_steps.sh was executed successfully twice consecutively in this run.
  • The proof uses an isolated Docker network and local registry, so it is repeatable and does not depend on an external attacker registry after initial base-image/tool downloads.
  • The fixed v2.2.5 negative control still pulls the attacker base image for checkpoint restore, but it no longer creates the arbitrary victim tag. This distinction matches the reproduced exploit chain and is why the subsequent victim CreateContainer/StartContainer cannot execute attacker code on the fixed build.

Variant Analysis & Alternative Triggers for CVE-2026-50195

Versions: versions as tested for the alternate trigger: vulnerable official v2.2.2 runtime (containerd ... v2.2.2 301b2dac98f15c27117da5c8af12118a041a31d9) is affected.Fixed: versions as tested: official v2.2.5 runtime (containerd ... v2.2.5 e53c7c1516c3b2bff98eb76f1f4117477e6f4e66) blocks the alternate trigger.

No bypass of the patched containerd CRI checkpoint-import fix was found. I tested a meaningful alternate trigger that uses a digest-form checkpoint config.dump field (rootfsImageRef=NAME@DIGEST) instead of the parent reproduction's tag-form rootfsImageRef=NAME:TAG, while still setting attacker-controlled rootfsImageName to an arbitrary victim tag. This alternate encoding reproduces the same tag-poisoning/code-execution chain on vulnerable containerd v2.2.2, but the fixed v2.2.5 runtime blocks it: the attacker base image is pulled/resolved, but no arbitrary victim tag is created and the later victim container cannot start.

Fix Coverage / Assumptions

The fix relies on a direct invariant: untrusted checkpoint metadata may be used to identify the base image needed for checkpoint restore, but it must not create or overwrite local image names. In vulnerable v2.2.2, internal/cri/server/container_checkpoint_linux.go in (*criService).CRImportCheckpoint reads config.RootfsImageRef, obtains/pulls that image, then copies the image service record and calls ImageService().Create after replacing tagImage.Name with untrusted config.RootfsImageName. Fixed v2.2.5 removes that retagging block.

Covered code paths:

  • CRI CreateContainer with a local checkpoint tar path, detected in internal/cri/server/container_create.go and passed to CRImportCheckpoint.
  • CRI CreateContainer with an OCI checkpoint image resolved by checkIfCheckpointOCIImage, because after metadata extraction it reaches the same CRImportCheckpoint logic.
  • Tag-form and digest-form RootfsImageRef values, because the fix removes creation of RootfsImageName regardless of the reference syntax.

No uncovered same-sink path was confirmed. Local trusted-administrator commands such as explicitly running ctr images tag are outside the CRI trust boundary and were not treated as valid vulnerability variants.

Variant / Alternate Trigger

Tested alternate trigger: digest-form rootfsImageRef inside attacker-supplied checkpoint metadata.

  • Entrypoint kind: api_remote.
  • Entrypoint detail: CRI gRPC runtime endpoint, CreateContainer where image.image points to a checkpoint tar archive.
  • Attacker-controlled fields:
    • config.dump.rootfsImageRef=localhost:5000/attacker-digest@sha256:6015e02e94c8a0760f2ec65a62684d1ee6fb84925e68386f83e912ef8f9431af
    • config.dump.rootfsImageName=localhost:5000/victim-digest:stable
  • Code path:
    • internal/cri/server/container_create.go: checkpoint image/file detection and call to CRImportCheckpoint.
    • internal/cri/server/container_checkpoint_linux.go: CRImportCheckpoint reads config.dump, pulls/resolves RootfsImageRef, and, only in vulnerable versions, creates the arbitrary RootfsImageName tag.

The candidate is materially different from the parent reproduction because the pulled image identity uses NAME@DIGEST, which is also the form described in the checkpoint import comments for legitimate checkpoint metadata. It still crosses the same CRI trust boundary and reaches the same sink.

Runtime results:

  • Vulnerable v2.2.2: alternate trigger confirmed. The import created both the attacker digest image and the victim tag, and later StartContainer for the victim tag executed attacker image code.

  • Fixed v2.2.5: no bypass. The import pulled/resolved the attacker digest image but did not create the victim tag; later victim CreateContainer failed with image not found.

  • Package/component affected: github.com/containerd/containerd/v2, CRI checkpoint import implementation.

  • Affected versions as tested for the alternate trigger: vulnerable official v2.2.2 runtime (containerd ... v2.2.2 301b2dac98f15c27117da5c8af12118a041a31d9) is affected.

  • Fixed versions as tested: official v2.2.5 runtime (containerd ... v2.2.5 e53c7c1516c3b2bff98eb76f1f4117477e6f4e66) blocks the alternate trigger.

  • Risk on vulnerable versions: critical, same as the parent issue. A checkpoint import can poison a local image tag so a later normal CRI container runs attacker-controlled image content.

Impact Parity

  • Disclosed/claimed maximum impact for parent: code execution through CRI checkpoint import by pulling/running attacker image content.
  • Reproduced impact from this variant run: code execution on vulnerable v2.2.2. The victim container created from localhost:5000/victim-digest:stable printed PRUVA_DIGEST_VARIANT_CODE_EXEC uid=0 gid=0 image=attacker-digest.
  • Parity: partial for variant-stage outcome overall. The alternate trigger has full impact parity on vulnerable versions, but it is not a bypass because fixed v2.2.5 blocks it.
  • Not demonstrated: no code execution on the fixed target; that absence is the expected negative-control result.

Root Cause

The same underlying root cause is reachable on vulnerable versions: checkpoint metadata is trusted as image-store authority. In v2.2.2, CRImportCheckpoint pulls/resolves config.RootfsImageRef and then creates a local image service record named by config.RootfsImageName. The candidate changes only the syntax of RootfsImageRef from a tag reference to a digest reference; the vulnerable sink still sees an image service record for the pulled digest and writes a new local victim tag for it.

The fix is effective because it removes the vulnerable image-service creation step rather than trying to validate a subset of reference syntaxes. Therefore the digest-form candidate does not bypass v2.2.5: RootfsImageRef may still be pulled, but RootfsImageName is not materialized as a local tag.

Fix commit identity was not resolved to a single upstream patch commit in this run, but the tested release identities were recorded:

  • v2.2.2 tag source: 116b799b27bcb69462e26db2d70c4823211befeb; release binary reports commit 301b2dac98f15c27117da5c8af12118a041a31d9.
  • v2.2.5 tag source: bafc09e8fb5c3d754f57a77cd0b1fc6b7919834d; release binary reports commit e53c7c1516c3b2bff98eb76f1f4117477e6f4e66.
  • v2.3.2 tag source was also recorded as c2be8504d753b8e360526e405e27c4164595daf6 for latest fixed-branch context.

Reproduction Steps

  1. Run bundle/vuln_variant/reproduction_steps.sh from the run root or with PRUVA_ROOT set to the bundle root.
  2. The script:
    • Starts an isolated local Docker registry on a non-conflicting host port.
    • Builds/pushes a pause image, an attacker digest image, and a legitimate victim image.
    • Builds privileged runner images containing official containerd v2.2.2 and v2.2.5 release binaries.
    • For each runtime, drives the real CRI socket with crictl runp, crictl create, and crictl start.
    • Imports a malicious checkpoint archive where rootfsImageRef is NAME@DIGEST and rootfsImageName is a distinct victim tag.
    • Checks whether the victim tag was created and whether a later normal victim container executes attacker image code.
  3. Expected evidence:
    • v2.2.2: POST-CHECKPOINT: poisoned victim digest tag entries = 1 and PRUVA_DIGEST_VARIANT_CODE_EXEC in victim logs.
    • v2.2.5: POST-CHECKPOINT: poisoned victim digest tag entries = 0, victim CreateContainer fails with not found, and no attacker marker appears.

Per stage convention the script exits 1 because no fixed-version bypass was found, even though the script completed successfully and produced evidence. It was executed twice successfully and idempotently.

Evidence

Primary evidence files:

  • bundle/logs/vuln_variant/digest_variant_summary.txt — concise vulnerable/fixed verdict summary.
  • bundle/logs/vuln_variant/vulnerable_v222_digest_variant_evidence.txt — full vulnerable run evidence.
  • bundle/logs/vuln_variant/fixed_v225_digest_variant_evidence.txt — fixed negative-control evidence.
  • bundle/logs/vuln_variant/vulnerable_v222_digest_containerd_version.txt — vulnerable runtime identity.
  • bundle/logs/vuln_variant/fixed_v225_digest_containerd_version.txt — fixed runtime identity.
  • bundle/logs/vuln_variant/source_identity_discovery.txt — source tag identities and patch hunk.
  • bundle/vuln_variant/runtime_manifest.json — runtime manifest for the candidate attempt.

Key excerpts:

Vulnerable result: VULN_DIGEST_TRIGGER_CONFIRMED
attacker digest ref=localhost:5000/attacker-digest@sha256:6015e02e94c8a0760f2ec65a62684d1ee6fb84925e68386f83e912ef8f9431af
POST-CHECKPOINT: attacker digest image entries = 1
POST-CHECKPOINT: poisoned victim digest tag entries = 1
PRUVA_DIGEST_VARIANT_CODE_EXEC uid=0 gid=0 image=attacker-digest
Fixed result: FIXED_DIGEST_TRIGGER_BLOCKED
POST-CHECKPOINT: attacker digest image entries = 1
POST-CHECKPOINT: poisoned victim digest tag entries = 0
victim CreateContainer failed (expected for fixed runtime when no poisoned tag exists)
VERDICT: FIXED_DIGEST_TRIGGER_BLOCKED - fixed runtime pulled/resolved the base image but did not create the arbitrary victim tag

Environment details captured:

  • Docker privileged runner with real containerd CRI plugin.
  • Official containerd v2.2.2 and v2.2.5 release binaries.
  • runc, CNI ptp/portmap, crictl, and local registry:2.

Recommendations / Next Steps

  • Preserve the v2.2.5 behavior that removes all ImageService().Create / arbitrary retagging based on checkpoint metadata.
  • Add regression tests for both tag-form and digest-form RootfsImageRef values where RootfsImageName differs from the pulled image identity. The assertion should be that no RootfsImageName image-store record is created.
  • Include both checkpoint archive and OCI checkpoint image import paths in regression coverage, since both converge on CRImportCheckpoint after metadata extraction.
  • Treat future uses of checkpoint RootfsImageName, RootfsImageRef, status.image, and status.image_ref as untrusted metadata unless they are checked against authenticated image-store state.

Additional Notes

  • The target's public security policy/reporting docs were reviewed before variant classification.
  • The stage-specific reproduction script was executed twice. Both runs completed and produced the same negative-bypass verdict.
  • The script's nonzero exit code is intentional for this negative outcome: exit 0 is reserved for a confirmed fixed-version bypass; exit 1 means no bypass/variant on the fixed target was reproduced.

CVE-2026-50195 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:000:56
0:00
session startedaccounts/fireworks/routers/glm-5p2-fast · CVE-2026-50195 · REPRO-20
0:02
0:04
web search
0:05
web search
0:08
0:09
0:11
web search
0:14
0:15
web search
0:17
web search
0:26
0:27
extract_facts
no facts extracted
0:28
0:28
0:28
supportrepro
0:42
0:44
0:44
0:44
0:45
0:46
0:46
0:48
0:48
0:52
0:52
$cd /data/pruva/project-cache/9e790cda-4e27-4fc2-9ed7-a2678dd1691a/repo && git log --oneline -20 && echo "---VERSION---" && cat version/version.go && echo "---STATUS---" && git status && echo "---DESCRIBE---" && git describe --tags 2>/dev/null || echo "no tags describe"
0.2s
{"cwd":"/data/pruva/runs/baed833a-b876-4531-9a22-8e8362fc5e5b","duration_ms":208,"exit_code":0,"stderr":"","stdout":"301b2dac9 Merge pull request #12998 from samuelkarp/prepare-release-2.2.2\n7e6ecf434 Prepare release notes for v2.2.2\n5dc7bb27e Merge pull request #12987 from k8s-infra-cherrypick-robot/cherry-pick-12617-to-release/2.2\na20dead7c set default config_path in plugin init\n8b085dd5d Merge pull request #12936 from fidencio/release-2.2/backport-12835\n7022bea84 Merge pull request #12957 from k8s-infra-cherrypick-robot/cherry-pick-12950-to-release/2.2\n68855cb0b ci: modprobe xt_comment on almalinux\n46fabcc77 Merge pull request #12944 from k8s-infra-cherrypick-robot/cherry-pick-12941-to-release/2.2\nef7a8beb3 core/mount: add test for getUnprivilegedMountFlags\n07b2cc07e core/mount: fix getUnprivilegedMountFlags iterating over indices instead of values\na5f83d8c2 cri: unpack images with per-layer labels for runtime-specific snapshotters\n842cbd07e Merge pull request #12926 from k8s-infra-cherrypick-robot/cherry-pick-12923-to-release/2.2\n54101116f add integration test for cni result nil\nd44c4384e address comment\nf1835270b fix issue where cni del is never executed\n3661d86… [truncated]
0:56

Artifacts and Evidence for CVE-2026-50195

Scripts, logs, diffs, and output captured during the reproduction.

bundle/artifact_promotion_manifest.json11.4 KB
bundle/vuln_variant/root_cause_equivalence.json1.6 KB
bundle/repro/reproduction_steps.sh22.3 KB
bundle/repro/rca_report.md8.6 KB
bundle/repro/runtime_manifest.json1.4 KB
bundle/repro/validation_verdict.json0.8 KB
bundle/logs/exploit_evidence.txt0.7 KB
bundle/logs/containerd.log16.4 KB
bundle/logs/attacker_marker.txt0.1 KB
bundle/logs/crictl_ps.txt0.4 KB
bundle/logs/vulnerable_v222_exploit_evidence.txt5.0 KB
bundle/logs/fixed_v225_exploit_evidence.txt4.2 KB
bundle/logs/vulnerable_v222_exploit_stdout.log4.9 KB
bundle/logs/vulnerable_v222_containerd.log17.7 KB
bundle/logs/vulnerable_v222_ctr_images.txt1.7 KB
bundle/logs/vulnerable_v222_crictl_ps.txt0.6 KB
bundle/logs/vulnerable_v222_podlogs.txt0.1 KB
bundle/logs/fixed_v225_exploit_stdout.log4.0 KB
bundle/logs/fixed_v225_containerd.log17.0 KB
bundle/logs/fixed_v225_ctr_images.txt1.4 KB
bundle/logs/fixed_v225_crictl_ps.txt0.4 KB
bundle/logs/source/patch_check.txt3.4 KB
bundle/logs/reproduction_steps.log8.9 KB
bundle/vuln_variant/reproduction_steps.sh21.8 KB
bundle/logs/vuln_variant/digest_variant_summary.txt1.0 KB
bundle/logs/vuln_variant/vulnerable_v222_digest_variant_evidence.txt5.0 KB
bundle/logs/vuln_variant/fixed_v225_digest_variant_evidence.txt4.5 KB
bundle/vuln_variant/variant_manifest.json4.0 KB
bundle/vuln_variant/validation_verdict.json3.0 KB
bundle/vuln_variant/rca_report.md10.1 KB
bundle/vuln_variant/patch_analysis.md6.6 KB
bundle/vuln_variant/runtime_manifest.json0.9 KB
bundle/logs/vuln_variant/reproduction_steps.log8.5 KB
08 · How to Fix

How to Fix CVE-2026-50195

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-50195 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-50195

How does the CVE-2026-50195 attack work?

An attacker imports a malicious checkpoint archive through the containerd CRI gRPC socket, poisoning a local tag such as localhost:5000/victim:stable to resolve to an attacker-controlled image (e.g. localhost:5000/attacker:latest). A subsequent normal container creation using that poisoned tag runs the attacker's image command instead of the legitimate one, printing evidence of code execution as root.

Which containerd versions are affected by CVE-2026-50195, and where is it fixed?

Containerd versions before 2.3.2, 2.2.5, and 2.1.9 are affected. The reproduction confirms v2.2.2 is vulnerable and v2.2.5 is a fixed negative control.

How severe is CVE-2026-50195?

Critical. An attacker who can submit a crafted CRI checkpoint archive can poison a node's local image cache and cause subsequent containers using the poisoned tag to execute attacker-controlled code, potentially as root.

How can I reproduce CVE-2026-50195?

Download the verified script from this page and run it in an isolated environment against containerd v2.2.2. It imports a malicious checkpoint archive via the CRI gRPC socket to poison a local image tag, then creates and starts a normal container from that tag and confirms the attacker image's command executes as root; confirm v2.2.5 blocks the poisoning.
11 · References

References for CVE-2026-50195

Authoritative sources for CVE-2026-50195 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.