This Week in Security: Discord, Chromium, and WordPress Forced Updates

[Masato Kinugawa] found a series of bugs that, when strung together, allowed remote code execution in the Discord desktop app. Discord’s desktop application is an Electron powered app, meaning it’s a web page rendered on a bundled light-weight browser. Building your desktop apps on JavaScript certainly makes life easier for developers, but it also means that you inherit all the problems from running a browser and JS. There’s a joke in there about finally achieving full-stack JavaScript.

The big security problem with Electron is that a simple Cross Site Scripting (XSS) bug is suddenly running in the context of the desktop, instead of the browser. Yes, there is a sandboxing option, but that has to be manually enabled.

And that brings us to the first bug. Neither the sandbox nor the contextIsolation options were set, and so both defaulted to false. What does this setting allow an attacker to do? Because the front-end and back-end JavaScript runs in the same context, it’s possible for an XSS attack to override JS functions. If those functions are then called by the back-end, they have full access to Node.js functions, including exec(), at which point the escape is complete.

Now that we know how to escape Electron’s web browser, what can we use for an XSS attack? The answer is automatic iframe embeds. For an example, just take a look at the exploit demo below. On the back-end, all I have to do is paste in the YouTube link, and the WordPress editor does its magic, automatically embedding the video in an iframe. Discord does the same thing for a handful of different services, one being Sketchfab.

This brings us to vulnerability #2. Sketchfab embeds have an XSS vulnerability. A specially crafted sketchfab file can run some JS whenever a user interacts with the embedded player, which can be shoehorned into discord. We’re almost there, but there is still a problem remaining. This code is running in the context of an iframe, not the primary thread, so we still can’t override functions for a full escape. To actually get a full RCE, we need to trigger a navigation to a malicious URL in the primary pageview, and not just the iframe. There’s already code to prevent an iframe from redirecting the top page, so this RCE is a bust, right?

Enter bug #3. If the top page and the iframe are on different domains, the code preventing navigation never fires. In this case, JavaScript running in an iframe can redirect the top page to a malicious site, which can then override core JS functions, leading to a full escape to RCE.

It’s a very clever chaining of vulnerabilities, from the Discord app, to an XSS in Sketchfab, to a bug within Electron itself. While this particular example required interacting with the embedded iframe, it’s quite possible that another vulnerable service has an XSS bug that doesn’t require interaction. In any case, if you use Discord on the desktop, make sure the app is up to date. And then, enjoy the demo of the attack, embedded below.

Chromium Freetype Overflow

Chromium 86 has a fix for a particularly nasty bug. Tracked as CVE-2020-15999, this is a bug in how FreeType fonts are rendered. Now that Microsoft has switched to Edgium (Chromium powered Edge), we get two-for-one deals on Chromium vulnerabilities. This bug is interesting because it’s reportedly being actively exploited already. Google has marked the bug public, so we can take a closer look at exactly what happened.

The problem is in the FreeType library, regarding how fonts are handled when they contain embedded PNGs. To put it simply, the PNG width and height are stored in the font as 32-bit values, but those values are truncated to 16-bit before the buffer is allocated. After this, the PNG is copied to the buffer, but using the non-truncated values. A check is then performed to make sure the copy didn’t overflow, but unhelpfully, this was checked *after* the copy had taken place. The bug includes a test case, so feel free to go check your devices using that code. It’s not clear how long this bug has existed, but it’s possible it also affects Android’s System WebView, which is much slower to update.

Step-by-step of Chrome Exploit

[Man Yue Mo] recently published a detailed report on a Use-After-Free Chrome bug he discovered back in March, tracked as CVE-2020-6449. What makes this one worth looking at is the detailed account he gives us of the process of developing a working exploit from the bug. The whole account is a masterclass in abusing JavaScript to manipulate the state of the underlying engine. As a bonus, he gives us a link to the PoC exploit code to look at, too.

FBI Warning

The FBI, along with CISA and HHS, has issued a warning (PDF) about an ongoing redoubling of ransomware attacks against US hospitals and other healthcare providers. This attack is using the Trickbot malware and the Ryuk ransomware. They also note the use of DNS tunneling for data exfiltration, and specifically mention Point of Sale systems as a target.

The mitigation steps are particularly interesting in trying to read between the lines here. Before we look too deeply, I have to call out an outdated piece of advice: “Regularly change passwords”. This has been the bane of many users and administrators, and leads to weaker security, not stronger. With that out of the way, let’s look at the other recommendations.

A few recommendations are boiler-plate, like two-factor authentication, install security updates, have backups, etc. I was surprised to see the recommendation to allow local administration, in order to get things working again. What might be the most interesting is the recommendation to take a hard look at any RDP services that are running. Does this mean that some healthcare PoS system is running an out-of-date Windows, with a vulnerable RDP service open to the network by default, and it’s suddenly being targeted? Maybe. I’ve learned not to put too much stock in these advisories, unless actual details are given, and this particular example is quite light on details.

Loginizer’s SQL Injection

The popular Loginizer WordPress plugin is intended to protect your site’s login page from attack. It can add two-factor authentication, CAPTCHAs for repeated login attempts, and even detect brute-force attempts and blacklist the offending IP. That last one is where the problem lies. Incoming login attempts are logged to a SQL database, and that logging wasn’t properly sanitized, nor were prepared statements used. Because of this, the login page was subject to a very simple SQL injection attack. The Lesson? Sanitize your inputs, and use prepared statements! The latest update fixes this, as well as a separate but similar security issue.

What makes this bug novel is that WordPress found it a big enough problem to break the glass and push the big red button labeled “Force Update”. I didn’t know the folks at WordPress had a button that did that, but for particularly bad bugs like this one, it’s a useful capability. A few users complained that this update was installed even though they had auto-updates disabled. It’s a fine line to walk here, but it seems like WordPress should make it clear in the settings that this feature exists, and include a way to opt-out of forced updates like this one.