← Back to Feed CACHED · 2026-09-23 10:44:35 · CACHE_KEY CVE-2026-79699
CVE-2026-79699 · CWE-59 · Disclosed 2026-09-15

A flaw was found in the containers/storage library.

ASSESSED — NOISGATE
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

Someone left a trapdoor label on a shipping container, but the forklift ignores it

CVE-2026-79699 is a flaw in the containers/storage Go library — the layer-unpacking engine underneath Podman, Buildah, and Skopeo. A crafted OCI/Docker image layer containing a malicious .wh. (whiteout) header can trick storage/pkg/archive.UnpackLayer, ApplyLayer, or ApplyUncompressedLayer into replacing the extraction destination directory with an attacker-controlled file. Affected library versions: all releases of github.com/containers/storage, and go.podman.io/storage before 1.62.1 (1.62.x branch) and before 1.64.1 (1.64.x branch). Downstream consumers include Podman (fixed in v5.8.7 and v6.1.2), Buildah, Skopeo, RHEL 8/9/10, OpenShift Container Platform 4, Red Hat Quay 3, and Azure Linux 3.

Red Hat rates this MEDIUM 4.4 (CVSS:3.1) while the GitHub Security Advisory (GHSA-mmq6-9mjh-hvq3) scores it Moderate 6.1 — the disagreement hinges on whether integrity impact is Low or High. Crucially, the Podman maintainers added an explicit caveat in the v5.8.7 and v6.1.2 release notes: *"we do not believe these CVEs are exploitable through the Podman command line."* That statement, combined with zero public PoCs and an EPSS of 0.13%, tells us the vendor severity already overstates real-world risk. The bug is academically interesting — whiteout handling is subtle — but requires a victim to pull a malicious image and hit a code path that the primary consumer (Podman) cannot even reach.

"Vendor says not exploitable via CLI; no PoC, no exploitation. Backlog-tier patch."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Craft malicious OCI layer

The attacker constructs a tar archive containing a whiteout entry (.wh. prefix) with a path-traversal payload that references the extraction destination directory itself. This layer is embedded in a container image and pushed to a registry the victim will pull from. Tools like tar and crane can assemble arbitrary layer content.
Conditions required:
  • Attacker can publish to a container registry the victim trusts or browses
Where this breaks in practice:
  • Most enterprises pull from curated internal registries, not arbitrary public repos
  • Registry scanning (Trivy, Clair, Quay security scanning) inspects layer content pre-pull
Detection/coverage: Container image scanners (Trivy ≥ 0.62, Grype ≥ 0.93) flag known CVEs in pulled images; layer-content scanners can detect anomalous whiteout entries.
STEP 02

Victim pulls the malicious image

A developer or CI pipeline runs podman pull, buildah from, or skopeo copy referencing the attacker's image. The containers/storage library begins extracting layers via UnpackLayer or ApplyLayer.
Conditions required:
  • Victim runs Podman < 5.8.7 / < 6.1.2, or an unpatched Buildah/Skopeo version
  • Victim explicitly pulls the malicious image tag or digest
Where this breaks in practice:
  • Podman maintainers state this code path is not reachable through the Podman CLI — the vulnerable branch requires a specific internal API invocation pattern
  • Buildah and Skopeo *may* reach the path, but no researcher has demonstrated it
  • Image pull is an interactive decision; automated pipelines pin digests
Detection/coverage: Pull events are logged by container runtimes and can be audited in CI logs. SELinux and AppArmor container profiles restrict file-write targets.
STEP 03

Whiteout header replaces extraction directory

The malicious .wh. entry causes the library to replace the extraction destination directory with an attacker-supplied file. This is a local file-overwrite primitive constrained to the storage root (typically /var/lib/containers/storage). The overwrite affects integrity of the local layer store, not arbitrary host paths.
Conditions required:
  • The vulnerable UnpackLayer/ApplyLayer code path is actually reached (disputed by vendor)
  • Process has write access to the container storage directory
Where this breaks in practice:
  • Overwrite is scoped to the container storage root — not arbitrary filesystem paths
  • On rootless Podman, the storage root is inside $HOME/.local/share/containers with user-level privileges only
  • SELinux container_var_lib_t labels prevent writes outside the storage tree
Detection/coverage: File-integrity monitoring on /var/lib/containers/storage would flag unexpected overwrites. Audit logs capture file operations under the storage directory.
STEP 04

Attacker leverages overwritten file

To achieve meaningful impact, the attacker would need the overwritten file to be subsequently consumed by a privileged process — for example, a corrupted layer blob re-used during a podman build or buildah commit. The realistic outcome is denial of service (corrupted storage) rather than code execution.
Conditions required:
  • The overwritten file must be in a location that influences a subsequent privileged operation
  • A privileged process must consume the corrupted file without validation
Where this breaks in practice:
  • No demonstrated path from file overwrite to code execution
  • Corrupted storage typically causes build failures, not exploitation — the blast radius is self-limiting
  • Container storage is ephemeral and frequently recreated
Detection/coverage: Build failures and storage corruption errors are highly visible in CI logs.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. Not listed in CISA KEV. No campaigns, ransomware, or threat-actor usage reported as of 2026-09-23.
Proof of conceptNo public PoC. GHSA-mmq6-9mjh-hvq3 credits Arpit Jain (@arpitjain099) as the reporter. No exploit code published. Podman maintainers explicitly state the flaw is not exploitable through the CLI.
EPSS0.0013 (0.13% probability of exploitation in 30 days, 3rd percentile) — bottom of the distribution.
KEV statusNot listed. No CISA due date.
CVSS interpretationRed Hat: 4.4 (AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L). GHSA: 6.1 (AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:L). Disagreement on integrity impact (L vs H). Local-only, requires user interaction, no confidentiality impact. Neither vector reaches network-reachable.
Affected versionsgo.podman.io/storage < 1.62.1 and ≥ 1.63.0 < 1.64.1. Legacy github.com/containers/storage — all versions (vendor advises migration). Downstream: Podman < 5.8.7 / < 6.1.2, RHEL 8/9/10, OCP 4, Quay 3, Azure Linux 3 (skopeo ≤ 1.14.4-12).
Fixed versionsgo.podman.io/storage 1.62.1 and 1.64.1 (commit 67d3951). Podman v5.8.7 (5.x LTS) and v6.1.2 (6.x). RHEL/OCP errata pending. Debian: no fix published yet.
Exposure surfaceNot network-exploitable. No Shodan/GreyNoise/Censys signal — this is a local library flaw, not a listening service. Exposure is governed by who pulls untrusted container images on unpatched hosts.
Disclosure timelineReported 2026-08-25 → Published 2026-09-15 → Podman patches released 2026-09-16 (next-day turnaround).
ReporterArpit Jain (@arpitjain099), security researcher. Contributed to Anchore/Grype and other container-security projects.
04 · The Call

Final Verdict
DOWNGRADED to LOW (3.2/10)

Why this verdict

  • Vendor non-exploitability statement: The Podman maintainers — who *wrote* the affected code — explicitly state in the v5.8.7 and v6.1.2 release notes that they "do not believe these CVEs are exploitable through the Podman command line." When the upstream author says the primary consumer can't reach the vulnerable path, that is the strongest possible friction signal.
  • No PoC, no exploitation, basement-tier EPSS: Zero public exploit code, zero in-the-wild activity, EPSS at the 3rd percentile (0.13%). The vulnerability was disclosed a week ago with a same-day patch; if it were easily weaponizable, researchers would have a PoC by now.
  • Local-only, user-interaction-required, scoped overwrite: CVSS AV:L/UI:R means an attacker cannot reach this remotely. The victim must actively pull a malicious image. The overwrite is constrained to the container storage directory, not arbitrary host filesystem paths. On rootless Podman the blast radius is a user-owned directory.
  • Role multiplier — CI/CD (Buildah): Buildah in CI/CD pipelines is the most plausible high-value-role consumer. In theory, a supply-chain attack via a poisoned base image could hit the vulnerable UnpackLayer path during buildah from. However: (a) the vendor has not confirmed Buildah CLI is reachable either, (b) overwrite is scoped to the storage root, not build output, (c) CI pipelines that pin image digests and use internal registries are not reachable. The chain does not succeed with domain/fleet/supply-chain blast radius — at worst it corrupts a build worker's local storage (host-level). This does not trigger the HIGH floor.
  • Role multiplier — OpenShift/CRI-O nodes: OCP nodes use CRI-O, which also links containers/storage. But CRI-O's image-pull path goes through different extraction code and is subject to cluster-level image policies. No evidence this path is reachable in CRI-O. Host-level blast radius at most; does not reach fleet-scale.
  • GHSA vs Red Hat scoring discrepancy: GHSA rates integrity as High (6.1) while Red Hat rates it Low (4.4). Red Hat's assessment — from the team that maintains the code — is more credible. The overwrite replaces the *extraction directory*, not arbitrary filesystem locations. I:L is correct.

Why not higher?

The only path to MEDIUM or above would require a demonstrated PoC showing exploitation through a real CLI tool (Podman, Buildah, or Skopeo) with impact beyond the container storage directory — such as arbitrary host file overwrite or code execution. None of that exists. The vendor's own "not exploitable through CLI" statement, combined with EPSS at the 3rd percentile and zero exploitation evidence, makes even MEDIUM unsupportable. The CI/CD supply-chain scenario is theoretical and unvalidated.

Why not lower?

IGNORE would be appropriate only if the flaw were entirely non-exploitable or affected dead code. The vulnerable functions (UnpackLayer, ApplyLayer) are real, actively used code paths in a widely-deployed library. A fix was committed and shipped within 24 hours of disclosure, which means the maintainers took it seriously enough to patch. The library is embedded in RHEL, OCP, and every Podman installation — the installed base is enormous even if exploitability is low. This warrants tracking and eventual patching, not outright dismissal.

05 · Compensating Control

What to do — in priority order.

  1. Update containers/storage to ≥ 1.62.1 or ≥ 1.64.1 — The definitive fix. Per the noisgate remediation SLA for LOW, treat this as backlog hygiene — no hard deadline, but roll it into your next scheduled container-tooling update cycle. Podman v5.8.7 / v6.1.2 bundle the fix.
  2. Pin container image references to digests in CI/CD pipelines — Prevents substitution attacks where an attacker pushes a malicious tag. Use image@sha256:... instead of image:latest. This eliminates the supply-chain delivery vector entirely.
  3. Restrict registry sources to internal mirrors — Configure Podman/Buildah registries.conf to only pull from vetted internal registries. Blocks the attacker's ability to serve a malicious image to your fleet.
  4. Enable container image scanning in CI — Run Trivy, Grype, or Clair on every pulled image. Layer-level scanning can flag anomalous whiteout entries and known CVEs in base images before they reach build workers.
  5. Run Podman/Buildah rootless where possible — Rootless mode constrains the storage directory to $HOME/.local/share/containers, limiting any file-overwrite impact to user-owned paths. Combined with SELinux, this makes host-level impact negligible.
What doesn't work
  • Network segmentation / firewall rules — This is a local library flaw triggered by image content, not a network service. Firewalling does nothing to prevent exploitation.
  • WAF or IDS/IPS — No network traffic signature to match. The malicious payload is inside a container image layer (tar archive), not an HTTP request.
  • Disabling whiteout processing — There is no configuration knob in containers/storage to disable whiteout handling. Whiteouts are a fundamental part of overlay filesystem semantics; disabling them would break all multi-layer images.
06 · Verification

Crowdsourced verification payload.

Run on each container host or CI build worker where Podman, Buildah, or Skopeo is installed. Requires read access to the Go module cache or the installed binary. Example: sudo bash check_cve_2026_79699.sh

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-79699 checker — containers/storage whiteout directory replacement
# Run on hosts with Podman, Buildah, or Skopeo installed.
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

RESULT="UNKNOWN"

check_version() {
  local tool="$1"
  local ver
  ver=$("$tool" --version 2>/dev/null | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' | head -1) || return 1
  echo "[*] Found $tool version: $ver"
  echo "$ver"
}

version_gte() {
  # Returns 0 if $1 >= $2
  printf '%s\n%s' "$2" "$1" | sort -V -C
}

# Check Podman
if command -v podman &>/dev/null; then
  PODMAN_VER=$(check_version podman)
  if [ -n "$PODMAN_VER" ]; then
    MAJOR=$(echo "$PODMAN_VER" | cut -d. -f1)
    if [ "$MAJOR" -eq 5 ]; then
      if version_gte "$PODMAN_VER" "5.8.7"; then
        echo "[+] Podman $PODMAN_VER >= 5.8.7 — PATCHED"
        RESULT="PATCHED"
      else
        echo "[-] Podman $PODMAN_VER < 5.8.7 — VULNERABLE"
        RESULT="VULNERABLE"
      fi
    elif [ "$MAJOR" -ge 6 ]; then
      if version_gte "$PODMAN_VER" "6.1.2"; then
        echo "[+] Podman $PODMAN_VER >= 6.1.2 — PATCHED"
        RESULT="PATCHED"
      else
        echo "[-] Podman $PODMAN_VER < 6.1.2 — VULNERABLE"
        RESULT="VULNERABLE"
      fi
    elif [ "$MAJOR" -le 4 ]; then
      echo "[-] Podman $PODMAN_VER (v4.x or older) — VULNERABLE (EOL branch)"
      RESULT="VULNERABLE"
    fi
  fi
fi

# Check Buildah
if command -v buildah &>/dev/null; then
  BUILDAH_VER=$(check_version buildah)
  if [ -n "$BUILDAH_VER" ]; then
    echo "[*] Buildah $BUILDAH_VER detected — cross-reference with go.podman.io/storage version"
    # Buildah doesn't directly expose storage lib version; flag if Podman wasn't found
    if [ "$RESULT" = "UNKNOWN" ]; then
      echo "[!] Cannot determine patch status from Buildah version alone."
      echo "[!] Check: go list -m go.podman.io/storage 2>/dev/null in the build environment."
    fi
  fi
fi

# Check Skopeo
if command -v skopeo &>/dev/null; then
  SKOPEO_VER=$(check_version skopeo)
  if [ -n "$SKOPEO_VER" ]; then
    echo "[*] Skopeo $SKOPEO_VER detected — cross-reference with go.podman.io/storage version"
  fi
fi

# Try to check the Go module directly if available
if command -v go &>/dev/null; then
  STORAGE_VER=$(go list -m -json go.podman.io/storage 2>/dev/null | grep -oP '"Version":\s*"v?\K[0-9.]+' || true)
  if [ -n "$STORAGE_VER" ]; then
    echo "[*] go.podman.io/storage module version: $STORAGE_VER"
    if version_gte "$STORAGE_VER" "1.64.1"; then
      echo "[+] storage >= 1.64.1 — PATCHED"
      RESULT="PATCHED"
    elif version_gte "$STORAGE_VER" "1.63.0"; then
      echo "[-] storage >= 1.63.0 but < 1.64.1 — VULNERABLE"
      RESULT="VULNERABLE"
    elif version_gte "$STORAGE_VER" "1.62.1"; then
      echo "[+] storage >= 1.62.1 (1.62.x branch) — PATCHED"
      RESULT="PATCHED"
    else
      echo "[-] storage < 1.62.1 — VULNERABLE"
      RESULT="VULNERABLE"
    fi
  fi
fi

if ! command -v podman &>/dev/null && ! command -v buildah &>/dev/null && ! command -v skopeo &>/dev/null; then
  echo "[*] No Podman/Buildah/Skopeo found — not affected."
  RESULT="PATCHED"
fi

echo ""
echo "=== CVE-2026-79699 STATUS: $RESULT ==="

case "$RESULT" in
  PATCHED)    exit 0 ;;
  VULNERABLE) exit 1 ;;
  *)          exit 2 ;;
esac
07 · Sources

Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.