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

KubeVirt Affected by an Authentication Bypass in Kubernetes Aggregation Layer

CVE-2025-64432

Description

KubeVirt is a virtual machine management add-on for Kubernetes. Versions 1.5.3 and below, and 1.6.0 contained a flawed implementation of the Kubernetes aggregation layer's authentication flow which could enable bypass of RBAC controls. It was discovered that the virt-api component fails to correctly authenticate the client when receiving API requests over mTLS. In particular, it fails to validate the CN (Common Name) field in the received client TLS certificates against the set of allowed values defined in the extension-apiserver-authentication configmap. Failre to validate certain fields in the client TLS certificate may allow an attacker to bypass existing RBAC controls by directly communicating with the aggregated API server, impersonating the Kubernetes API server and its aggregator component. This issue is fixed in versions 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
kubevirt.io/kubevirtGo
>= 1.7.0-alpha.0, < 1.7.0-rc.01.7.0-rc.0

Affected products

1

Patches

3
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
    
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
    

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.