CVE-2025-13281 Overview
CVE-2025-13281 is a half-blind Server-Side Request Forgery (SSRF) vulnerability in the Kubernetes kube-controller-manager component. The flaw exists in the in-tree Portworx StorageClass provisioner. Authorized users can coerce the controller to issue arbitrary HTTP requests from the control plane host. These requests originate from the control plane's network namespace, giving attackers reach into unprotected internal endpoints. Reachable targets include cloud metadata services on link-local addresses and loopback-bound services on the control plane host. The vulnerability is classified under CWE-918: Server-Side Request Forgery.
Critical Impact
Authenticated users with StorageClass permissions can leak sensitive data from control plane host-network services, including loopback and link-local endpoints such as 169.254.169.254 metadata services.
Affected Products
- Kubernetes kube-controller-manager configured with the in-tree Portworx volume plugin
- Kubernetes clusters exposing the Portworx StorageClass provisioner to tenant users
- Managed and self-hosted Kubernetes distributions that have not migrated Portworx storage to the CSI driver
Discovery Timeline
- 2025-12-14 - CVE-2025-13281 published to the National Vulnerability Database (NVD)
- 2026-06-17 - Last updated in the NVD database
Technical Details for CVE-2025-13281
Vulnerability Analysis
The vulnerability resides in the in-tree Portworx volume provisioner executed by kube-controller-manager. When a user creates a PersistentVolumeClaim bound to a Portworx StorageClass, the controller issues an HTTP request based on parameters influenced by the StorageClass definition. The provisioner does not sufficiently validate or restrict the destination of these requests. As a result, an authorized user who can define or reference a StorageClass can direct the controller to make requests toward arbitrary hosts. Because the controller runs inside the control plane's host network, its requests can reach loopback services and link-local metadata endpoints normally unreachable from workload pods. The response handling leaks partial data back to the requester through error messages or object status fields, making the SSRF half-blind rather than fully blind.
Root Cause
The root cause is missing destination validation in the in-tree Portworx StorageClass provisioner code path within kube-controller-manager. StorageClass parameters that influence the outbound request URL are treated as trusted input. No allow-list of endpoints or network scope restriction is applied before the HTTP client executes the request.
Attack Vector
An authenticated user with rights to create PersistentVolumeClaims against a Portworx StorageClass can trigger the vulnerable code path. The attacker crafts StorageClass parameters or PVC references so the controller directs its HTTP request to a chosen internal host. Response data, error text, or object status leaks a portion of the response back to the requester. Attackers can enumerate loopback services, retrieve cloud instance metadata, or map internal control plane endpoints. Refer to the Kubernetes security announcement and GitHub issue #135525 for upstream technical details.
No verified exploit code is publicly available. The vulnerability mechanism is documented in prose form only; see the Openwall oss-security advisory for coordinated disclosure details.
Detection Methods for CVE-2025-13281
Indicators of Compromise
- Outbound HTTP requests from kube-controller-manager process to link-local addresses such as 169.254.169.254 or loopback interfaces
- StorageClass or PersistentVolumeClaim objects referencing unusual Portworx endpoint parameters or non-standard host values
- Controller manager log entries showing HTTP client errors containing partial response bodies from internal services
- PVC status or event messages containing text fragments consistent with metadata service responses
Detection Strategies
- Audit Kubernetes API server logs for create and update operations on storageclasses.storage.k8s.io and persistentvolumeclaims referencing the Portworx provisioner
- Correlate PVC creation events with anomalous outbound network activity from control plane nodes
- Baseline expected destinations for kube-controller-manager egress traffic and alert on deviations to internal address ranges
Monitoring Recommendations
- Enable Kubernetes audit logging at Metadata level or higher for storage-related resources and forward logs to a centralized analytics platform
- Monitor host-level network telemetry on control plane nodes for connections initiated by kube-controller-manager to 169.254.0.0/16, 127.0.0.0/8, and other internal ranges
- Review RBAC bindings granting create on persistentvolumeclaims and identify unexpected principals with access to Portworx StorageClasses
How to Mitigate CVE-2025-13281
Immediate Actions Required
- Upgrade kube-controller-manager to a patched Kubernetes release as identified in the Kubernetes security announcement
- Migrate Portworx storage integration from the in-tree provisioner to the Portworx CSI driver where supported
- Restrict RBAC permissions so only trusted service accounts can create or modify StorageClasses referencing Portworx
- Apply network policies or host firewall rules on control plane nodes to block egress from the controller manager to metadata and loopback endpoints where feasible
Patch Information
Refer to the upstream fix and version guidance in Kubernetes GitHub issue #135525 and the Kubernetes security announcement. Cluster operators should apply the fixed minor or patch release corresponding to their deployed Kubernetes version.
Workarounds
- Disable the in-tree Portworx volume plugin via the --disable-in-tree-plugin or equivalent feature gate configuration on kube-controller-manager when the CSI driver is available
- Remove or restrict StorageClasses that reference the in-tree Portworx provisioner until patches are applied
- Enforce admission controls, such as validating admission policies, to reject StorageClass parameters targeting internal or link-local address ranges
# Example: audit cluster for in-tree Portworx StorageClasses
kubectl get storageclass -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.provisioner}{"\n"}{end}' \
| grep -i 'kubernetes.io/portworx-volume'
# Example: list principals with permission to create PVCs
kubectl get rolebindings,clusterrolebindings --all-namespaces -o wide \
| grep -Ei 'edit|admin|storage'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

