Hackerman's Hacking Tutorials

The knowledge of anything, since all things have causes, is not acquired or complete unless it is known by its causes. - Avicenna

Jun 8, 2021 - 4 minute read - Comments - Attack Surface Analysis

The JavaScript Bridge in Modern Desktop Applications

We have an XSS in a desktop application, what happens next? How can you escalate it to remote code execution? Let's see.

Modern desktop applications are mostly1 based on Chromium. There are three major frameworks:

There also some miscellaneous frameworks like NW.js. I have only seen a single commercial app using this framework and it was six years ago when I was still doing consulting at good ole' Cigital.

What's The JavaScript Bridge?

There are two kinds of browser-based desktop applications:

  1. Just displays a website in Electron, e.g., Trello.
  2. Also interacts with the machine, e.g., Steam.

The JavaScript bridge is a set of APIs that allow the web content in the application to interact with the host machine. In Steam (based on CEF), you click on the install button on a web page displayed in the app and a game gets installed on your machine. The web page button calls some JavaScript and eventually it uses the JavaScript bridge to do stuff on the machine.

Why is The JavaScript Bridge Important?

Rogue JavaScript (e.g., via XSS) can use it to jump the browser sandbox and do bad things to the underlying machine.

XSS Happens (lol)

Parsia 2 am thought while playing Anthem

"But I am not gonna have XSS, Parsia." You will, my friend. Even if you do everything right, you might get hit by a framework bypass.

Examples

As is tradition, we're gonna review public bugs. That's how I learn.

Razer Comms - CEF

Years ago (probably around 2015), I looked at Razer Comms. Think of it as the precursor to Discord. Razer Comms was a CEF app and I managed to get a few trivial XSS instances there.

Not knowing what to do next, the best I could do was show a prompt to phish user's passwords. Now, I wish I had explored the JavaScript bridge to see what else I could have done.

Is this the best I could do? Is this the best I could do?

I never disclosed them and published a post after it was retired:

Origin XSS to RCE - QtWebEngine

Disclosure: I work for EA and Origin is one of our products.

I have used this bug numerous times. There are a few reasons:

  1. It's a cool bug.
  2. It's one of the few public Origin bugs I can talk about.
  3. I know Origin like the back of my hand (at least I think so).

XSS happened because of an AngularJS sandbox bypass. This is one of those situations when you can do everything correctly but get hit. We see a typical alert.

But the last section named The Third Bug (RCE) explores the JavaScript bridge. Origin is using the QtWebEngine to display web pages and the Origin.client.desktopServices API is available. The weapon of choice is asyncOpenUrl which allows us to pass a scheme (including file:/// to execute files), but no parameters.

Overwolf XSS to RCE - CEF

This is a new one by Joel Noguera of SwordBytes Security. You should read it:

I am not gonna go through the blog post, but here's a summary (quoting myself again lol):

CEF App -> Protocol Handler -> Send request -> Response has XSS -> XSS calls JavaScript bridge API -> Write file with API -> Execute file with API

Let's focus on the Escaping the CEF sandbox section. The Overwolf JavaScript bridge provides a openUrlInDefaultBrowser(url) which is similar to what we have seen before. We can open URL/file or execute files without parameters.

But there's also writeFileContents which allows writing a file to disk. The rest of the path is clear, write a bat file (or an HTA file if you feel fancy) and then execute it with the previous API.

Electron - Not Again!

I have purposefully not talked about Electron in this post. Electron has the ultimate JavaScript bridge with nodeIntegration. I have talked about it a lot. Even, when it's disabled, RCE happens (this is a great writeup, btw). With the Electron defaults becoming more secure, we need to start using the techniques in this blog.

Here's a ton of examples (including two of mine):

What Did We Learn Here Today?

XSS happens. After you get XSS in a modern desktop app, start poking the JavaScript bridge to jump out of the Chromium sandbox.


  1. I say almost because I might be missing some but I have never seen desktop apps based on another browser. ↩︎