VYPR
Moderate severityNVD Advisory· Published Nov 7, 2025· Updated Nov 10, 2025

KubeVirt Improper TLS Certificate Management Handling Allows API Identity Spoofing

CVE-2025-64434

Description

KubeVirt is a virtual machine management add-on for Kubernetes. Prior to 1.5.3 and 1.6.1, due to the peer verification logic in virt-handler (via verifyPeerCert), an attacker who compromises a virt-handler instance, could exploit these shared credentials to impersonate virt-api and execute privileged operations against other virt-handler instances potentially compromising the integrity and availability of the VM managed by it. This vulnerability is fixed in 1.5.3 and 1.6.1.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
kubevirt.io/kubevirtGo
< 1.5.31.5.3
kubevirt.io/kubevirtGo
>= 1.6.0-alpha.0, < 1.6.11.6.1

Affected products

1

Patches

3
b9773bc588e6

SetupTLSWithCertManager now enforces CN

https://github.com/kubevirt/kubevirtLuboslav PivarcJul 14, 2025via ghsa
3 files changed · +55 4
  • pkg/util/tls/tls.go+29 1 modified
    @@ -17,6 +17,7 @@ import (
     )
     
     const noSrvCertMessage = "No server certificate, server is not yet ready to receive traffic"
    +const serverNotReadyMsg = "Server is not yet ready to receive traffic"
     
     var (
     	cipherSuites         = tls.CipherSuites()
    @@ -91,7 +92,7 @@ func SetupExportProxyTLS(certManager certificate.Manager, kubeVirtStore cache.St
     	return tlsConfig
     }
     
    -func SetupTLSWithCertManager(caManager ClientCAManager, certManager certificate.Manager, clientAuth tls.ClientAuthType, clusterConfig *virtconfig.ClusterConfig) *tls.Config {
    +func SetupTLSWithCertManager(caManager KubernetesCAManager, certManager certificate.Manager, clientAuth tls.ClientAuthType, clusterConfig *virtconfig.ClusterConfig) *tls.Config {
     	tlsConfig := &tls.Config{
     		GetCertificate: func(info *tls.ClientHelloInfo) (certificate *tls.Certificate, err error) {
     			cert := certManager.Current()
    @@ -122,6 +123,33 @@ func SetupTLSWithCertManager(caManager ClientCAManager, certManager certificate.
     				Certificates: []tls.Certificate{*cert},
     				ClientCAs:    clientCAPool,
     				ClientAuth:   clientAuth,
    +				VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
    +					if len(verifiedChains) == 0 || len(verifiedChains[0]) == 0 {
    +						return nil
    +					}
    +
    +					certificate, err := x509.ParseCertificate(rawCerts[0])
    +					if err != nil {
    +						return fmt.Errorf("failed to parse peer certificate: %v", err)
    +					}
    +
    +					CNs, err := caManager.GetCNs()
    +					if err != nil {
    +						log.Log.Reason(err).Error(serverNotReadyMsg)
    +						return fmt.Errorf(serverNotReadyMsg)
    +					}
    +
    +					if len(CNs) == 0 {
    +						return nil
    +					}
    +					for _, CN := range CNs {
    +						if certificate.Subject.CommonName == CN {
    +							return nil
    +						}
    +					}
    +
    +					return fmt.Errorf("Common name is invalid")
    +				},
     			}
     
     			config.BuildNameToCertificate()
    
  • pkg/util/tls/tls_test.go+25 2 modified
    @@ -31,6 +31,7 @@ import (
     
     type mockCAManager struct {
     	caBundle []byte
    +	cns      []string
     }
     
     type mockCertManager struct {
    @@ -66,9 +67,13 @@ func (m *mockCAManager) GetCurrentRaw() ([]byte, error) {
     	return nil, fmt.Errorf("not implemented")
     }
     
    +func (m *mockCAManager) GetCNs() ([]string, error) {
    +	return m.cns, nil
    +}
    +
     var _ = Describe("TLS", func() {
     
    -	var caManager kvtls.ClientCAManager
    +	var caManager kvtls.KubernetesCAManager
     	var certmanagers map[string]certificate.Manager
     	var clusterConfig *virtconfig.ClusterConfig
     	var kubeVirtStore cache.Store
    @@ -220,7 +225,8 @@ var _ = Describe("TLS", func() {
     		}),
     	)
     
    -	DescribeTable("should verify self-signed client and server certificates", func(serverSecret, clientSecret string, errStr string) {
    +	DescribeTable("should verify self-signed client and server certificates", func(serverSecret, clientSecret, errStr string, cns []string) {
    +		caManager.(*mockCAManager).cns = cns
     		serverTLSConfig := kvtls.SetupTLSWithCertManager(caManager, certmanagers[serverSecret], tls.RequireAndVerifyClientCert, clusterConfig)
     		clientTLSConfig := kvtls.SetupTLSForVirtHandlerClients(caManager, certmanagers[clientSecret], false)
     		srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    @@ -248,18 +254,35 @@ var _ = Describe("TLS", func() {
     			components.VirtHandlerServerCertSecretName,
     			components.VirtHandlerCertSecretName,
     			"",
    +			[]string{"kubevirt.io:system:client:virt-handler"},
    +		),
    +		Entry(
    +			"connect with proper certificates with no CN auth",
    +			components.VirtHandlerServerCertSecretName,
    +			components.VirtHandlerCertSecretName,
    +			"",
    +			[]string{},
    +		),
    +		Entry(
    +			"fail if client uses an invalid certificates (CN)",
    +			components.VirtHandlerServerCertSecretName,
    +			components.VirtHandlerCertSecretName,
    +			"remote error: tls: bad certificate",
    +			[]string{"kubevirt.io:system:clientv2:virt-handler"},
     		),
     		Entry(
     			"fail if client uses an invalid certificate",
     			components.VirtHandlerServerCertSecretName,
     			components.VirtHandlerServerCertSecretName,
     			"remote error: tls: bad certificate",
    +			[]string{"kubevirt.io:system:client:virt-handler"},
     		),
     		Entry(
     			"fail if server uses an invalid certificate",
     			components.VirtHandlerCertSecretName,
     			components.VirtHandlerCertSecretName,
     			"x509: certificate specifies an incompatible key usage",
    +			[]string{"kubevirt.io:system:client:virt-handler"},
     		),
     	)
     
    
  • pkg/virt-api/api.go+1 1 modified
    @@ -960,7 +960,7 @@ func (app *virtAPIApp) registerMutatingWebhook(informers *webhooks.Informers) {
     	})
     }
     
    -func (app *virtAPIApp) setupTLS(k8sCAManager kvtls.ClientCAManager, kubevirtCAManager kvtls.ClientCAManager) {
    +func (app *virtAPIApp) setupTLS(k8sCAManager kvtls.KubernetesCAManager, kubevirtCAManager kvtls.ClientCAManager) {
     
     	// A VerifyClientCertIfGiven request means we're not guaranteed
     	// a client has been authenticated unless they provide a peer
    
231dc69723f3

SetupTLSWithCertManager now enforces CN

https://github.com/kubevirt/kubevirtLuboslav PivarcJul 14, 2025via ghsa
3 files changed · +55 4
  • pkg/util/tls/tls.go+29 1 modified
    @@ -17,6 +17,7 @@ import (
     )
     
     const noSrvCertMessage = "No server certificate, server is not yet ready to receive traffic"
    +const serverNotReadyMsg = "Server is not yet ready to receive traffic"
     
     var (
     	cipherSuites         = tls.CipherSuites()
    @@ -91,7 +92,7 @@ func SetupExportProxyTLS(certManager certificate.Manager, kubeVirtStore cache.St
     	return tlsConfig
     }
     
    -func SetupTLSWithCertManager(caManager ClientCAManager, certManager certificate.Manager, clientAuth tls.ClientAuthType, clusterConfig *virtconfig.ClusterConfig) *tls.Config {
    +func SetupTLSWithCertManager(caManager KubernetesCAManager, certManager certificate.Manager, clientAuth tls.ClientAuthType, clusterConfig *virtconfig.ClusterConfig) *tls.Config {
     	tlsConfig := &tls.Config{
     		GetCertificate: func(info *tls.ClientHelloInfo) (certificate *tls.Certificate, err error) {
     			cert := certManager.Current()
    @@ -122,6 +123,33 @@ func SetupTLSWithCertManager(caManager ClientCAManager, certManager certificate.
     				Certificates: []tls.Certificate{*cert},
     				ClientCAs:    clientCAPool,
     				ClientAuth:   clientAuth,
    +				VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
    +					if len(verifiedChains) == 0 || len(verifiedChains[0]) == 0 {
    +						return nil
    +					}
    +
    +					certificate, err := x509.ParseCertificate(rawCerts[0])
    +					if err != nil {
    +						return fmt.Errorf("failed to parse peer certificate: %v", err)
    +					}
    +
    +					CNs, err := caManager.GetCNs()
    +					if err != nil {
    +						log.Log.Reason(err).Error(serverNotReadyMsg)
    +						return fmt.Errorf(serverNotReadyMsg)
    +					}
    +
    +					if len(CNs) == 0 {
    +						return nil
    +					}
    +					for _, CN := range CNs {
    +						if certificate.Subject.CommonName == CN {
    +							return nil
    +						}
    +					}
    +
    +					return fmt.Errorf("Common name is invalid")
    +				},
     			}
     
     			config.BuildNameToCertificate()
    
  • pkg/util/tls/tls_test.go+25 2 modified
    @@ -31,6 +31,7 @@ import (
     
     type mockCAManager struct {
     	caBundle []byte
    +	cns      []string
     }
     
     type mockCertManager struct {
    @@ -66,9 +67,13 @@ func (m *mockCAManager) GetCurrentRaw() ([]byte, error) {
     	return nil, fmt.Errorf("not implemented")
     }
     
    +func (m *mockCAManager) GetCNs() ([]string, error) {
    +	return m.cns, nil
    +}
    +
     var _ = Describe("TLS", func() {
     
    -	var caManager kvtls.ClientCAManager
    +	var caManager kvtls.KubernetesCAManager
     	var certmanagers map[string]certificate.Manager
     	var clusterConfig *virtconfig.ClusterConfig
     	var kubeVirtStore cache.Store
    @@ -220,7 +225,8 @@ var _ = Describe("TLS", func() {
     		}),
     	)
     
    -	DescribeTable("should verify self-signed client and server certificates", func(serverSecret, clientSecret string, errStr string) {
    +	DescribeTable("should verify self-signed client and server certificates", func(serverSecret, clientSecret, errStr string, cns []string) {
    +		caManager.(*mockCAManager).cns = cns
     		serverTLSConfig := kvtls.SetupTLSWithCertManager(caManager, certmanagers[serverSecret], tls.RequireAndVerifyClientCert, clusterConfig)
     		clientTLSConfig := kvtls.SetupTLSForVirtHandlerClients(caManager, certmanagers[clientSecret], false)
     		srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    @@ -248,18 +254,35 @@ var _ = Describe("TLS", func() {
     			components.VirtHandlerServerCertSecretName,
     			components.VirtHandlerCertSecretName,
     			"",
    +			[]string{"kubevirt.io:system:client:virt-handler"},
    +		),
    +		Entry(
    +			"connect with proper certificates with no CN auth",
    +			components.VirtHandlerServerCertSecretName,
    +			components.VirtHandlerCertSecretName,
    +			"",
    +			[]string{},
    +		),
    +		Entry(
    +			"fail if client uses an invalid certificates (CN)",
    +			components.VirtHandlerServerCertSecretName,
    +			components.VirtHandlerCertSecretName,
    +			"remote error: tls: bad certificate",
    +			[]string{"kubevirt.io:system:clientv2:virt-handler"},
     		),
     		Entry(
     			"fail if client uses an invalid certificate",
     			components.VirtHandlerServerCertSecretName,
     			components.VirtHandlerServerCertSecretName,
     			"remote error: tls: bad certificate",
    +			[]string{"kubevirt.io:system:client:virt-handler"},
     		),
     		Entry(
     			"fail if server uses an invalid certificate",
     			components.VirtHandlerCertSecretName,
     			components.VirtHandlerCertSecretName,
     			"x509: certificate specifies an incompatible key usage",
    +			[]string{"kubevirt.io:system:client:virt-handler"},
     		),
     	)
     
    
  • pkg/virt-api/api.go+1 1 modified
    @@ -990,7 +990,7 @@ func (app *virtAPIApp) registerMutatingWebhook(informers *webhooks.Informers) {
     	})
     }
     
    -func (app *virtAPIApp) setupTLS(k8sCAManager kvtls.ClientCAManager, kubevirtCAManager kvtls.ClientCAManager) {
    +func (app *virtAPIApp) setupTLS(k8sCAManager kvtls.KubernetesCAManager, kubevirtCAManager kvtls.ClientCAManager) {
     
     	// A VerifyClientCertIfGiven request means we're not guaranteed
     	// a client has been authenticated unless they provide a peer
    
af2f08a9a186

SetupTLSWithCertManager now enforces CN

https://github.com/kubevirt/kubevirtLuboslav PivarcJul 14, 2025via ghsa
3 files changed · +55 4
  • pkg/util/tls/tls.go+29 1 modified
    @@ -17,6 +17,7 @@ import (
     )
     
     const noSrvCertMessage = "No server certificate, server is not yet ready to receive traffic"
    +const serverNotReadyMsg = "Server is not yet ready to receive traffic"
     
     var (
     	cipherSuites         = tls.CipherSuites()
    @@ -91,7 +92,7 @@ func SetupExportProxyTLS(certManager certificate.Manager, kubeVirtStore cache.St
     	return tlsConfig
     }
     
    -func SetupTLSWithCertManager(caManager ClientCAManager, certManager certificate.Manager, clientAuth tls.ClientAuthType, clusterConfig *virtconfig.ClusterConfig) *tls.Config {
    +func SetupTLSWithCertManager(caManager KubernetesCAManager, certManager certificate.Manager, clientAuth tls.ClientAuthType, clusterConfig *virtconfig.ClusterConfig) *tls.Config {
     	tlsConfig := &tls.Config{
     		GetCertificate: func(info *tls.ClientHelloInfo) (certificate *tls.Certificate, err error) {
     			cert := certManager.Current()
    @@ -122,6 +123,33 @@ func SetupTLSWithCertManager(caManager ClientCAManager, certManager certificate.
     				Certificates: []tls.Certificate{*cert},
     				ClientCAs:    clientCAPool,
     				ClientAuth:   clientAuth,
    +				VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
    +					if len(verifiedChains) == 0 || len(verifiedChains[0]) == 0 {
    +						return nil
    +					}
    +
    +					certificate, err := x509.ParseCertificate(rawCerts[0])
    +					if err != nil {
    +						return fmt.Errorf("failed to parse peer certificate: %v", err)
    +					}
    +
    +					CNs, err := caManager.GetCNs()
    +					if err != nil {
    +						log.Log.Reason(err).Error(serverNotReadyMsg)
    +						return fmt.Errorf(serverNotReadyMsg)
    +					}
    +
    +					if len(CNs) == 0 {
    +						return nil
    +					}
    +					for _, CN := range CNs {
    +						if certificate.Subject.CommonName == CN {
    +							return nil
    +						}
    +					}
    +
    +					return fmt.Errorf("Common name is invalid")
    +				},
     			}
     
     			config.BuildNameToCertificate()
    
  • pkg/util/tls/tls_test.go+25 2 modified
    @@ -31,6 +31,7 @@ import (
     
     type mockCAManager struct {
     	caBundle []byte
    +	cns      []string
     }
     
     type mockCertManager struct {
    @@ -66,9 +67,13 @@ func (m *mockCAManager) GetCurrentRaw() ([]byte, error) {
     	return nil, fmt.Errorf("not implemented")
     }
     
    +func (m *mockCAManager) GetCNs() ([]string, error) {
    +	return m.cns, nil
    +}
    +
     var _ = Describe("TLS", func() {
     
    -	var caManager kvtls.ClientCAManager
    +	var caManager kvtls.KubernetesCAManager
     	var certmanagers map[string]certificate.Manager
     	var clusterConfig *virtconfig.ClusterConfig
     	var kubeVirtStore cache.Store
    @@ -220,7 +225,8 @@ var _ = Describe("TLS", func() {
     		}),
     	)
     
    -	DescribeTable("should verify self-signed client and server certificates", func(serverSecret, clientSecret string, errStr string) {
    +	DescribeTable("should verify self-signed client and server certificates", func(serverSecret, clientSecret, errStr string, cns []string) {
    +		caManager.(*mockCAManager).cns = cns
     		serverTLSConfig := kvtls.SetupTLSWithCertManager(caManager, certmanagers[serverSecret], tls.RequireAndVerifyClientCert, clusterConfig)
     		clientTLSConfig := kvtls.SetupTLSForVirtHandlerClients(caManager, certmanagers[clientSecret], false)
     		srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    @@ -248,18 +254,35 @@ var _ = Describe("TLS", func() {
     			components.VirtHandlerServerCertSecretName,
     			components.VirtHandlerCertSecretName,
     			"",
    +			[]string{"kubevirt.io:system:client:virt-handler"},
    +		),
    +		Entry(
    +			"connect with proper certificates with no CN auth",
    +			components.VirtHandlerServerCertSecretName,
    +			components.VirtHandlerCertSecretName,
    +			"",
    +			[]string{},
    +		),
    +		Entry(
    +			"fail if client uses an invalid certificates (CN)",
    +			components.VirtHandlerServerCertSecretName,
    +			components.VirtHandlerCertSecretName,
    +			"remote error: tls: bad certificate",
    +			[]string{"kubevirt.io:system:clientv2:virt-handler"},
     		),
     		Entry(
     			"fail if client uses an invalid certificate",
     			components.VirtHandlerServerCertSecretName,
     			components.VirtHandlerServerCertSecretName,
     			"remote error: tls: bad certificate",
    +			[]string{"kubevirt.io:system:client:virt-handler"},
     		),
     		Entry(
     			"fail if server uses an invalid certificate",
     			components.VirtHandlerCertSecretName,
     			components.VirtHandlerCertSecretName,
     			"x509: certificate specifies an incompatible key usage",
    +			[]string{"kubevirt.io:system:client:virt-handler"},
     		),
     	)
     
    
  • pkg/virt-api/api.go+1 1 modified
    @@ -990,7 +990,7 @@ func (app *virtAPIApp) registerMutatingWebhook(informers *webhooks.Informers) {
     	})
     }
     
    -func (app *virtAPIApp) setupTLS(k8sCAManager kvtls.ClientCAManager, kubevirtCAManager kvtls.ClientCAManager) {
    +func (app *virtAPIApp) setupTLS(k8sCAManager kvtls.KubernetesCAManager, kubevirtCAManager kvtls.ClientCAManager) {
     
     	// A VerifyClientCertIfGiven request means we're not guaranteed
     	// a client has been authenticated unless they provide a peer
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.