Authenticated SSRF with response body exfiltration via git credential verification endpoint
reported via email on 14 June 2026:
I have identified a server-side request forgery (SSRF) vulnerability in the git credential verification endpoint (POST /kapis/[resources.kubesphere.io/v1alpha2/git/verify](http://resources.kubesphere.io/v1alpha2/git/verify)), present in the current release v4.1.3.
The endpoint is granted to all authenticated KubeSphere users through the built-in authenticated GlobalRole, which includes an explicit RBAC rule permitting create on [resources.kubesphere.io/git](http://resources.kubesphere.io/git). No additional workspace or project membership is required.
The handler passes the caller-supplied remoteUrl field directly to go-git's origin.List(), which performs an outbound HTTP request (GET <remoteUrl>/info/refs?service=git-upload-pack) using the ks-apiserver's network identity. When the target returns a non-2xx response, go-git reads the HTTP response body and includes it in the error string. The handler then serialises this error as the message field in the JSON response returned to the caller. As a result, an attacker can reach internal hosts and services and exfiltrate portions of their HTTP responses.
I confirmed this behaviour with an in-process test against the actual kubesphere repository code. The test showed the internal server received the request at /info/refs, and the response body INTERNAL_SENSITIVE_DATA=secret123 was returned verbatim in the API error response.
The endpoint also accepts an optional secretRef field specifying a Kubernetes Secret by namespace and name. The ks-apiserver service account has cluster-wide Secret read access; it retrieves the credentials and sends them to the caller-supplied remoteUrl via HTTP Basic Auth. This allows any authenticated user to exfiltrate credentials from Secrets in any namespace (including kube-system) by pointing the remote URL at an attacker-controlled server.
Suggested fix: validate remoteUrl against a configurable allowlist of permitted hostname patterns (or deny private RFC 1918, link-local, and loopback addresses using a connect-time dialer hook similar to Go's dialer.Control pattern) before invoking go-git. Additionally, add an ownership or RBAC check so that a secretRef referencing a Secret in namespace N is only honoured for callers who hold get secrets permission in that namespace.
Source: kubesphere/kubesphere