GitHub Security Advisory: GHSA-ggp9-c99x-54gp
Package: kubevirt.io/kubevirt (GO)
Severity: MODERATE (CVSS 4.7)
CWE: CWE-287: Improper Authentication
Vulnerable versions: < 1.5.3
Patched in: 1.5.3

Summary: KubeVirt's Improper TLS Certificate Management Handling Allows API Identity Spoofing

Details:
### Summary
Due to improper TLS certificate management, a compromised `virt-handler` could impersonate `virt-api` by using its own TLS credentials, allowing it to initiate privileged operations against another `virt-handler`.

### Details
_Give all details on the vulnerability. Pointing to the incriminated source code is very helpful for the maintainer._

Because of improper TLS certificate management, a compromised `virt-handler` instance can reuse its TLS bundle to impersonate `virt-api`, enabling unauthorized access to VM lifecycle operations on other `virt-handler` nodes. 
The `virt-api` component acts as a sub-resource server, and it proxies API VM lifecycle requests to `virt-handler` instances.
The communication between `virt-api` and `virt-handler` instances is secured using mTLS. The former acts as a client while the latter as the server. The client certificate used by `virt-api` is defined in the source code as follows and have the following properties: 

```go
//pkg/virt-api/api.go

const (
	...
	defaultCAConfigMapName     = "kubevirt-ca"
  ...
	defaultHandlerCertFilePath = "/etc/virt-handler/clientcertificates/tls.crt"
	defaultHandlerKeyFilePath  = "/etc/virt-handler/clientcertificates/tls.key"
)
```

```bash
# verify virt-api's certificate properties from the docker container in which it is deployed using Minikube
admin@minikube:~$ openssl x509 -text -in \ 
$(CID=$(docker ps --filter 'Name=virt-api' --format '{{.ID}}' | head -n 1) && \
docker inspect $CID | grep "clientcertificates:ro" | cut -d ":" -f1 | \
tr -d '"[:space:]')/tls.crt | \
grep -e "Subject:" -e "Issuer:" -e "Serial"

Serial Number:[PII_REDACTED]12425330 (0x1c688e539091f72)
Issuer: CN = kubevirt.io@[PII_REDACTED]
Subject: CN = kubevirt.io:system:client:virt-handler
```

The `virt-handler` component verifies the signature of client certificates using a self-signed root CA. This latter is generated by `virt-operator` when the KubeVirt stack is deployed and it is stored within a ConfigMap in the `kubevirt` namespace. **This configmap is used as a trust anchor** by all `virt-handler` instances to verify client certificates.

```bash
# inspect the self-signed root CA used to sign virt-api and virt-handler's certificates
admin@minikube:~$ kubectl -n kubevirt get configmap kubevirt-ca -o jsonpath='{.data.ca-bundle}' | openssl x509 -text | grep -e "Subject:" -e "Issuer:" -e "Serial"

Serial Number:[PII_REDACTED]63923930 (0x46ea01e3f7427da)
Issuer: CN=kubevirt.io@[PII_REDACTED]
Subject: CN=kubevirt.io@[PII_REDACTED]
```

The `kubevirt-ca` is also used to sign the server certificate which is used by a `virt-handler` instance:


```bash
admin@minikube:~$ openssl x509 -text -in \ 
$(CID=$(docker ps --filter 'Name=virt-handler' --format '{{.ID}}' | head -n 1) && \
docker inspect $CID | grep "servercertificates:ro" | cut -d ":" -f1 | \
tr -d '"[:space:]')/tls.crt | \
grep -e "Subject:" -e "Issuer:" -e "Serial"

# the virt-handler's server ceriticate is issued by the same root CA
Serial Number: 75844502