CVE-2020-1764: Hard-Coded Signing Key in Kiali

Published

A hard-coded signing key in Kiali prior to version 1.15.1 allowed attackers to craft valid authentication tokens if Kiali was configured for password-based authentication. The hard-coded key could be overridden in by configuration, but Kiali’s documentation and website did not mention the option. Red Hat has issued CVE-2020-1764 and the Kiali developers have published a security advisory .

The Discovery

A few months ago I was working through standardizing our process for deploying and configuring Istio and Kiali when I stumbled onto an oddity: my Istio sessions were surviving the complete destruction and recreation of all cluster resources (i.e., Deployments, Pods, ConfigMaps, Secerts, etc.). I could consistently:

  1. Log into Kiali.
  2. Completely remove the Deployment, including the operator, and all Kubernetes resources (even the namespace).
  3. Redeploy Kiali, including changing the administrator password.
  4. Continue to use the previous Kiali session without logging back in.

Kiali is an extremely powerful dashboard for Istio. With an authentication bypass, an attacker could use Kiali to view pod logs and create new Istio resources, potentially rerouting traffic to a malicious website after TLS termination.

The Investigation

After confirming the behavior several times, I started by looking at the session cookie—which appeared to enable persistent access to any instance of Kiali. The cookie appeared to be JWT, so I copied it to jwt.io to examine it. The token included an issuer, subject and expiration, and that was all. Since the JWT was being accepted for authentication, my best guess was that the signature was trusted by the default Kiali configuration, so I wanted to know how Kiali was signing it.

I found the issue in config/config.go on line 365 :

363
364
365
366
LoginToken: LoginToken{
  ExpirationSeconds: 24 * 3600,
  SigningKey:        "kiali",
},

When Kiali starts up, it creates a new config struct and overwrites defaults based on runtime configuration. Unfortunately, as mentioned above, there was no documentation describing how to do so (or warning that you absolutely should). I quickly validated my find by minting my own JWTs signed with “kiali” and using them to successfully bypass authentication. But that wasn’t all.

It took me a couple of days to work through everything Kiali was doing, and at I stumbled onto a second problem. While stepping through the authentication workflow I had accidentally used a token I created the previous day. The token’s expiration time had passed, but it continued to be accepted by Kiali. After some more investigation, I discovered that Kiali was misusing the library it relied on for parsing and validating JWTs. In config/token.go, the GetTokenClaimsIfValid function calls the ParseWithClaims function of an external library, presumably relying on the library to verify the token has not passed its expiration. However, ParseWithClaims only validates the token signature. Ultimately, the token’s expiration was completely ignored.

After a couple of days of exploring Kiali and testing its password-based authentication workflow, I identified two vulnerabilities: a hard-coded secret that permitted full authentication bypass and an improper use of an external library that resulted in infinite session validity.

The Disclosure

The Kiali developers made it easy for me to responsibly disclose my findings, providing contact information for Red Hat’s security team. The team was extremely professional and supportive of a first-time “security researcher.” We’ve all heard horror storeis of large organizations threatening responsible researchers, but Red Hat was simply great to work with. After a reasonable amount of time to investigate the matter internally, develop patches, and draft security advisories, Red Hat issued two CVEs (CVE-2020-1762 and CVE-2020-1764 ) and published the patched releases.

Acknowledgement

I’m grateful to my employer, Akoya, LLC, for giving me the time to investigate this issue and work with Red Hat to responsibly disclose and resolve the vulnerability.