A few mongth ago, Google released a new product - Hangouts Chat application, which is surely an answer to Slack. Hangouts Chat might be used both in browser (at https://chat.google.com; requires G Suite account) and as a desktop or mobile application - to be downloaded from https://get.google.com/chat/.
A few months ago I was given a research grant to analyze the application and decide to focus on the desktop app.
Hangouts Chat - desktop app
After installing, it turned out that the desktop app is actually an Electron app. In fact, the desktop app just displays the web application hosted at https://chat.google.com.
It may therefore seem that looking for security issues in the Electron app will not differ from the web version. This is mostly true, with one important caveat. The web version, when displayed in a browser, contains an address bar. The address bar is in fact the only place where the user can tell if they trust the domain or not. Here’s what Michał Zalewski writes about it in Tangled Web:
In essence, the domain name in the URL shown in the browser’s address bar is one of the most important security indicators on the Web, as it allows users to quickly differentiate sites they trust and have done business with from the rest of the Internet.
However, in the Electron app, the address bar is missing. This means the the user must trust that the application itself serves content from https://chat.google.com but there is no reliable indicator that confirms it does.
So at this point I thought that maybe I’d be able to find a way to redirect the application to an external domain (other than chat.google.com), which in turn would allow a very reliable phishing. The user would be redirected to an external domain controlled by the attacker, with a login panel very similar to the original one from Googe. The user would not be able to tell that the panel is fake as the address bar is missing.
Looking for redirection
So I started with the simplest possible idea to redirect user to another domain. I will… just add a link to the external domain in the chat. And when the user clicks it, (s)he’ll get redirected.
This obviously didn’t work as external links were opened in the default browser.
Let’s not give up, though.
After further research, I noticed that links to chat.google.com were opened directly in the Electron app. It turned out, by the way, that when a user clicks a link that returns code other than 200 (like: https://chat.google.com/webchannel/events), the user must restart the application as there is no “Back” button ;)
A quite common way to bypass URL access rules is to abuse redirections (responses with code 3xx). I noticed that chat.google.com redirects to
https://chat.google.com/u/0/?hasBeenRedirected=true when navigating to a non-existent URL, like
https://chat.google.com/test123. So I defined a match/replace rule in Burp to rewrite the
hasBeenRedirected=true URL-s to
sekurak.pl to see what happens.
And this is how the application reacted:
This is amazing! It actually confirms that a 302 redirect might be abused to display arbitrary websites within Hangouts Chat window.
The only missing piece now is an actual redirect in https://chat.google.com.
Open redirect is a vulnerability which, in my opinion, tends to be overvalued. To cite Google from their Bug Hunter University page:
Open redirectors take you from a Google URL to another website chosen by whoever constructed the link. Some members of the security community argue that the redirectors aid phishing, because users may be inclined to trust the mouse hover tooltip on a link and then fail to examine the address bar once the navigation takes place.
I agree with the sentiment. In general users should trust the address bar as the only reliable security indicator. The thing is that it is no longer true in case of Electron. In Electron app we don’t have the address bar, hence the user is unable to confirm to identity of the website. So in this case, it is clearly a severe vulnerability.
The search for open redirect in https://chat.google.com turned out to be much easier than I had initially thought. Any URL under https://chat.google.com/accounts is redirected to https://accounts.google.com. For example, check this out:
https://chat.google.com/accounts/random-url. You should end up on
https://accounts.google.com/random-url after clicking.
The redirect to accounts.google.com is just a first step in the riddle. But in fact the most important one as there exists a well-known, publicly disclosed open redirect on accounts.google.com (credit: @teh_h3ck). Please refer to the original blog post to find out details but the idea is that basically I can redirect to my own domain, I just need to host stuff on
So the final open redirect from chat.google.com is as follows:
I then prepared a logon page resembling the one from Google - and now we can have a very credible phishing page :)
The user, as shown in the gif above, cannot know that they are on a fake page because the address bar is missing.
The same attack would not work in the web app:
As you can see, Electron applications, because of missing address bar, actually make open redirect great again. If you write an Electron app, make sure that the main window cannot be redirected to an external domain.
If you use Google Hangouts Chat, make sure to update. Google released a patch a few days ago.
Interestingly, Google was quite generous with the bounty for the bug and paid 7,500 USD. The bounty actually corresponds to code execution. I wasn’t able to escalate it to code execution but Matt Austin (@mattaustin) proved in a tweet that it could actually be done. Thank you and great work, Matt!
Thank you, Google, for the research grant, by the way! Otherwise, I would have probably never looked at the application.
Update: The original title of the post was: “Vulnerability in Hangouts Chat a.k.a. how Electron makes open redirect great again”. It sparked some backlash in social media and seemed click-baity hence I decided to change it to something more neutral.