OpenKruise PodProbeMarker is Vulnerable to SSRF via Unrestricted Host Field
Description
Kruise provides automated management of large-scale applications on Kubernetes. Prior to versions 1.8.3 and 1.7.5, PodProbeMarker allows defining custom probes with TCPSocket or HTTPGet handlers. The webhook validation does not restrict the Host field in these probe configurations. Since kruise-daemon runs with hostNetwork=true, it executes probes from the node network namespace. An attacker with PodProbeMarker creation permission can specify arbitrary Host values to trigger SSRF from the node, perform port scanning, and receive response feedback through NodePodProbe status messages. Versions 1.8.3 and 1.7.5 patch the issue.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Kruise's PodProbeMarker lacks Host field validation, enabling SSRF attacks from the node via custom probes.
Vulnerability
CVE-2026-24005 concerns an unrestricted Host field in PodProbeMarker's TCPSocket and HTTPGet probe configurations. The webhook validation does not check the Host value, allowing arbitrary destinations. Since kruise-daemon runs with hostNetwork=true [1], probes are executed from the node's network namespace, not from within a pod.
Exploitation
An attacker with PodProbeMarker creation permission can set the Host to internal addresses (e.g., 127.0.0.1, cloud metadata IPs, internal services) [2]. This triggers a server-side request forgery (SSRF) from the node. The attacker can perform port scanning by observing the response status in NodePodProbe status messages, which provide feedback on whether the probe succeeded [2].
Impact
Successful exploitation allows the attacker to probe internal network services, access cloud instance metadata (e.g., 169.254.169.254), and scan ports on internal hosts from the node's network. This can lead to information disclosure or further compromise within the cluster.
Mitigation
The issue is patched in versions 1.8.3 and 1.7.5 [4]. Users should upgrade OpenKruise to the latest patched version. No workaround is mentioned for unpatched versions, so restricting PodProbeMarker creation permissions is advised until an upgrade is possible.
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/openkruise/kruiseGo | >= 1.8.0, < 1.8.3 | 1.8.3 |
github.com/openkruise/kruiseGo | < 1.7.5 | 1.7.5 |
Affected products
2- openkruise/kruisev5Range: >= 1.8.0, < 1.8.3
Patches
194364b76adf3restrict host field in probe (#2309)
2 files changed · +50 −8
pkg/webhook/podprobemarker/validating/probe_create_update_handler.go+12 −1 modified@@ -241,7 +241,14 @@ func validateExecAction(exec *corev1.ExecAction, fldPath *field.Path) field.Erro } func validateTCPSocketAction(tcp *corev1.TCPSocketAction, fldPath *field.Path) field.ErrorList { - return ValidatePortNumOrName(tcp.Port, fldPath.Child("port")) + allErrors := field.ErrorList{} + if len(tcp.Host) > 0 { + allErrors = append(allErrors, field.Invalid(fldPath.Child("host"), tcp.Host, "host field in probes is not allowed")) + } + + allErrors = append(allErrors, ValidatePortNumOrName(tcp.Port, fldPath.Child("port"))...) + + return allErrors } var supportedHTTPSchemes = sets.New(corev1.URISchemeHTTP, corev1.URISchemeHTTPS) @@ -251,6 +258,10 @@ func validateHTTPGetAction(http *corev1.HTTPGetAction, fldPath *field.Path) fiel if len(http.Path) == 0 { allErrors = append(allErrors, field.Required(fldPath.Child("path"), "")) } + + if len(http.Host) > 0 { + allErrors = append(allErrors, field.Invalid(fldPath.Child("host"), http.Host, "host field in probes is not allowed")) + } if _, err := url.Parse(http.Path); err != nil { allErrors = append(allErrors, field.Invalid(fldPath.Child("path"), http.Path, "must be a valid URL path")) }
pkg/webhook/podprobemarker/validating/probe_validating_test.go+38 −7 modified@@ -225,6 +225,24 @@ func TestValidatingPodProbeMarker(t *testing.T) { }, expectErrList: 1, }, + { + name: "test10, invalid ppm", + getPpm: func() *appsv1alpha1.PodProbeMarker { + ppm := ppmDemo.DeepCopy() + ppm.Spec.Probes[0].Name = "" + return ppm + }, + expectErrList: 1, + }, + { + name: "test11, invalid ppm", + getPpm: func() *appsv1alpha1.PodProbeMarker { + ppm := ppmDemo.DeepCopy() + ppm.Spec.Probes[0].ContainerName = "" + return ppm + }, + expectErrList: 1, + }, } decoder := admission.NewDecoder(scheme) @@ -246,11 +264,9 @@ func TestValidateHandler(t *testing.T) { {Exec: &corev1.ExecAction{Command: []string{"echo"}}}, {TCPSocket: &corev1.TCPSocketAction{ Port: intstr.IntOrString{Type: intstr.Int, IntVal: int32(8000)}, - Host: "3.3.3.3", }}, {TCPSocket: &corev1.TCPSocketAction{ Port: intstr.IntOrString{Type: intstr.String, StrVal: "container-port"}, - Host: "3.3.3.3", }}, } for _, h := range successCases { @@ -264,11 +280,9 @@ func TestValidateHandler(t *testing.T) { {Exec: &corev1.ExecAction{Command: []string{}}}, {TCPSocket: &corev1.TCPSocketAction{ Port: intstr.IntOrString{Type: intstr.String, StrVal: "container-port-v2"}, - Host: "3.3.3.3", }}, {TCPSocket: &corev1.TCPSocketAction{ Port: intstr.IntOrString{Type: intstr.Int, IntVal: -1}, - Host: "3.3.3.3", }}, {HTTPGet: &corev1.HTTPGetAction{Path: "", Port: intstr.FromInt(0), Host: ""}}, {HTTPGet: &corev1.HTTPGetAction{Path: "/foo", Port: intstr.FromInt(65536), Host: "host"}}, @@ -277,7 +291,6 @@ func TestValidateHandler(t *testing.T) { Exec: &corev1.ExecAction{Command: []string{}}, TCPSocket: &corev1.TCPSocketAction{ Port: intstr.IntOrString{Type: intstr.String, StrVal: "container-port-v2"}, - Host: "3.3.3.3", }, }, { @@ -287,15 +300,13 @@ func TestValidateHandler(t *testing.T) { { TCPSocket: &corev1.TCPSocketAction{ Port: intstr.IntOrString{Type: intstr.String, StrVal: "container-port-v2"}, - Host: "3.3.3.3", }, HTTPGet: &corev1.HTTPGetAction{Path: "", Port: intstr.FromString(""), Host: ""}, }, { Exec: &corev1.ExecAction{Command: []string{}}, TCPSocket: &corev1.TCPSocketAction{ Port: intstr.IntOrString{Type: intstr.String, StrVal: "container-port-v2"}, - Host: "3.3.3.3", }, HTTPGet: &corev1.HTTPGetAction{Path: "", Port: intstr.FromString(""), Host: ""}, }, @@ -447,6 +458,16 @@ func TestValidateTCPSocketAction(t *testing.T) { }, fldPath: field.NewPath("field"), }, + { + tcp: &corev1.TCPSocketAction{ + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + Host: "127.0.0.1", + }, + fldPath: field.NewPath("field"), + }, } for _, cs := range errorCases { if getErrs := validateTCPSocketAction(cs.tcp, cs.fldPath); len(getErrs) == 0 { @@ -552,6 +573,16 @@ func TestValidateHTTPGetAction(t *testing.T) { }, expectErrs: 1, }, + { + name: "invalid host field", + httpGet: &corev1.HTTPGetAction{ + Host: "127.0.0.1", + Path: "/healthz", + Port: intstr.FromInt(8080), + Scheme: corev1.URISchemeHTTP, + }, + expectErrs: 1, + }, } for _, tc := range testCases {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-9fj4-3849-rv9gghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-24005ghsaADVISORY
- github.com/openkruise/kruise/commit/94364b76adf3e8a1749a31afe809a163bed29613ghsax_refsource_MISCWEB
- github.com/openkruise/kruise/releases/tag/v1.7.5ghsax_refsource_MISCWEB
- github.com/openkruise/kruise/releases/tag/v1.8.3ghsax_refsource_MISCWEB
- github.com/openkruise/kruise/security/advisories/GHSA-9fj4-3849-rv9gghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.