KASM-2022-0001 - NGINX configuration injection vulnerability
Some deployments of Kasm may be vulnerable to NGINX configuration injections if configured with default Zone settings and without a front-end proxy or L7 load balancer in front of Kasm.
Vulnerability Summary
By default, Kasm Workspaces will work behind any domain name. Kasm will use the HOST header on the HTTPS request to dynamically know what domain name is being used. Malicious users can modify the HTTP HOST header and thereby inject arbitrary configurations into dynamically created NGINX configurations. In order for this vulnerability to be taken advantage of, the following two items must be true.
The Kasm Workspaces deployment does not have another load balancer or reverse proxy in front that is configured to expect a certain hostname.
One of the following Zone settings is set as follows:
In the Kasm Zone settings, the Upstream Auth Address field is set to $request_host$.
In the Kasm Zone Settings, Proxy Connections is checked and the Proxy Hostname field is set to $request_host$
Proxy/Load Balancer
If the Kasm Workspaces deployment is behind a reverse proxy or layer 7 load balancer that is configured to match the domain name on a request, this vulnerability does not apply, as it would not be possible for an attacker to send a request to Kasm Workspaces with a HTTP host header that does not match the domain used in the URL. This can be tested using curl.
In this first example, the Workspaces deployment is behind a layer 7 load balancer, however, it is configured to send traffic to Kasm Workspaces by default. The first curl command shows the output of curling the main domain name with no alterations. The second curl command modifies the HOST header and sets it to something different than the domain name in the URL. Since the curl command returned the same output, we know that the load balancer in front of this Kasm deployment is allowing the host header to not match the request. This is typically because the load balancer/reverse proxy is configured to serve a single website and proxies everything to Workspaces regardless of the host header.
default:~$ curl https://kasm.example.com
<!doctype html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,shrink-to-fit=no"> <link id=favicon rel="shortcut icon" href=""> <title></title> <link href="index.fonts.css?e5d7f50f7a9d2a6b1a12" rel="stylesheet"><link href="index.styles.css?e5d7f50f7a9d2a6b1a12" rel="stylesheet"></head> <body class="app header-fixed sidebar-fixed aside-menu-fixed aside-menu-hidden"> <div id=root></div> <script type="text/javascript" src="index.bundle.js?e5d7f50f7a9d2a6b1a12"></script></body> </html>
default:~$ curl https://kasm.example.com --header "HOST: test.com"
<!doctype html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,shrink-to-fit=no"> <link id=favicon rel="shortcut icon" href=""> <title></title> <link href="index.fonts.css?e5d7f50f7a9d2a6b1a12" rel="stylesheet"><link href="index.styles.css?e5d7f50f7a9d2a6b1a12" rel="stylesheet"></head> <body class="app header-fixed sidebar-fixed aside-menu-fixed aside-menu-hidden"> <div id=root></div> <script type="text/javascript" src="index.bundle.js?e5d7f50f7a9d2a6b1a12"></script></body> </html>
This second example shows a site that has a reverse proxy/load balancer in front that does not allow for arbitrary host headers. The host header must match a configured domain name otherwise it is denied. Note that the first request is successful, the curl gets a redirect back. The second request, where the host header is forced to be different than the URL, is denied with a 403. Not all secure configurations will return a 403 if the HOST header does not match a config, the administrator has many options. The important thing to check is that when the HOST header is modified, the site does not return the Kasm Workspaces page.
default:~$ curl https://example.com
<html><body>You are being <a href="https://www.exmple.com/">redirected</a>.</body></html>default:~$
default:~$ curl https://example.com --header "HOST: test.com"
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>cloudflare</center>
</body>
</html>
default:~$
Zone Settings
If Kasm Workspaces does not have a load balancer/reverse proxy in front or the load balancer/reverse proxy is not configured to require an explicit hostname, then it is imperative that the zone settings are modified to ensure this vulnerability cannot be exploited.
See the following screenshot, the Allow Origin Domain, Upstream Auth Address, and Proxy Hostname fields have all been modified from the default $request_host$, to an explicit domain name.