This is going to be ElectroVault, pwning popular desktop apps while uncovering new attack services on Electron. So let's put it together. Thank you very much. Good afternoon, everyone, and thanks for coming to our talk. Let me ask you this. Have you ever wondered how secure it is to open a message within the desktop app you use to chat with your colleagues at work? Have you ever wondered how secure it is to open a source code which you just downloaded from the internet within your favorite source code editor? What do these Electron-based desktop applications have in common, and how fundamentally secure are they? Before a year, we set out to find an exact answer to discover what lurks beneath Electron applications, and throughout the course of one year of our research, we were able to find flaws in more than a dozen iconic applications used by millions of people and uncovered new attack surface within Electron. Hereby, I welcome everyone today to ElectroVault, where I will take you on a journey to pwn popular desktop applications while uncovering new attack surface on Electron. So for the agenda, off of our talk, first of all, I will start with what is Electron and the basics of Electron. Then I will explain different security settings which Electron provides. Then we will hack real-world applications, starting from the least restrictive to the most restrictive settings. And then I will disclose a novel flaw which we discovered within Electron.js framework. And at the end, I will end it with mitigations. So let's get started. So who are we? I am Aditya Purani, AKA Napstack. I'm a senior security engineer at a leading automotive company. My main areas of expertise are application security and blockchain. And on the weekend, I play CTFs with Perfect Blue. Joining me today is my colleague Max, AKA The Grand Pew. Max is a security researcher at AssetNode. And he has expertise in application security and blockchain and Max plays CTFs with Water Peddler. We have two other research members who were not able to join with us today on the stage, but I would like to introduce them as well. So we have Mohan, AKA Sirius, who is a security auditor at Cure53. And we have William Bowling, AKA Vax, who is a senior software developer at Biteable. So let's get started. So what is Electron? If you can build a website, then you can build a desktop application. That's the main concept behind Electron. Electron is a popular open source framework used by multiple iconic applications, such as Microsoft Teams, Discord, Slack, and others. Electron is built on top of Chromium and Node.js, which means that, by just using HTML, JavaScript, and CSS, you can ship an entirely cross-platform native desktop application. So before diving into the bugs, it is really important to understand the architecture of Electron. So for Electron, there are two types of processes. The first one is the main process, and the second one is a renderer process. So main process is the starting point of all the processes. The main process can create multiple renderer process using a class known as browser window. On the other hand, we have renderer process, which is used to render web pages using Chromium. And as Chromium is used, a lot of Chromium-related features are involved as well, such as Chrome multiple process, site isolation, and others. It is important to note that there can be only one main process. But there can be multiple renderer process. The way the main process and renderer process communicates with each other is through IPC, or inter-process communication module. As you can see in the diagram on the left side, we have a node shared library. These are the node primitives, which are provided to both the main process and the renderer process. And as it is not secure to provide node primitives to the renderer process, we have something known as browser window web preferences, or security settings, to limit the exposure of node primitives. So let's look how this all will look in a code. So here we have a main process. And first of all, we create a browser window with multiple web preferences, which are security settings with either true or false Boolean value. Then we load a URL, which is google.com. And then we define an IPC event, which is the current listener, known as open URL, which will listen for this open URL channel and invoke shell.open external with the argument. On the other side, for the renderer process, it is divided into two parts. The first one is preload.js. And preload scripts contain code that is loaded prior to the web page. So this script runs within the renderer context, but are granted more privileges by having access to electron and node.js APIs. So it can import a node.js library here. Context bridge, which you see here, is a way to safely expose an API to the web page, which can be later accessed using window object. So let's see how the web page would look like. So here we have a web page for google.com, which was just loaded by the main earlier. And it's a hello world web page where it uses window.electron.open.json. Open URL and passes an argument to invoke that channel on the main process. So as we noticed in the main process, we can set multiple security settings to describe what type of renderer process we want. So if the security setting is, for example, node integration is true and sandbox and context isolation is false, then it is the most insecure you can get. In this case, XSS is equal to RC. So it's not a good idea to use this setting. Electron developers also thought about the same. And they came up with a solution. And the solution was to introduce a new feature known as context isolation. So as you can see in this diagram, there is a slight change compared to the previous one. Now we have two different contexts. The first one is the application context, and the second one is an isolated context. So application context is the space where your web page JavaScript, JavaScript would run. Whereas the isolated context is where your preload and Electron's internal JavaScript code would run. So now we have a good segregation between that layers. So in this situation, the node primitives are only exposed to the isolated context and are not reachable by the web page. And this is a similar concept used by Chromium browser as well, where it is known as isolated world, where the extension, which you install in your browser, it's content script JavaScript runs on a different side compared to the web application JavaScript. So there is an isolation there. So throughout our talk, the attack surface would be the renderer process. And we will be start by abusing the least restrictive configuration, and then move on to the complex exploits. So to keep the slides clean, let us keep following terminologies in mind. So I talked about node integration, context isolation, and sandbox, but don't worry right now about node integration in workers and node integration in subframes. I'll talk about it in the coming slides. So first situation, everything is red. Node integration is true. Context isolation is false. And sandbox is false. In this case, it is very easy to get a shell as node is directly exposed to the renderer. So a web page can just do require, a child process and exact their own shell command. So the only thing you need to do as an attacker is to find a way to embed your JavaScript within the web page. So again, we return to our schematics and the circle which is mentioned in the red is the area which we are targeting at this point. So let's take a look at a real world case study where we were able to abuse this specific configuration to get RCE. So we will look at, VS Code Remote Code Execution, which bypasses the restricted mode. So VS Code is a very commonly used source code editor. And when you open a project within VS Code, it will prompt you that you want to load this project in a restricted mode, or you want to open it in unsafe mode. So this particular RCE, which I'm about to demonstrate, will work on a restricted mode of VS Code. So the bug here is we were able to find an XSS, in Markdown, which was subjected to very strict CSP and electron policy. And we were able to chain it with multiple bugs to get an RCE on an insecure window. So let's see how this works. So this diagram is the entire exploit chain for VS Code. And here you can see three squares, which are marked with different color. So there is one with green, orange, and red. So the square which is marked in green is running with the most tight electron configuration, which is the most secure. And our goal is to somehow go from that green to red. The red one is the one which is running with node integration true, which is the most insecure configuration, which I talked about earlier. So how do we do that? So if you know in VS Code, when you open a project, and when you load a Markdown, it is not rendered by default. So first of all, you need to create a malicious project. So first of all, you need to create a malicious project. And create a folder known as .VS Code. Within this folder, you can create a JSON file, which is settings.json, and you can enable Markdown Previewer. So as soon as this project will load, it will not just put a code block, but it will render the Markdown. So once a Markdown is rendered, you can put your own JavaScript to get XSS. But in the first window, the Markdown Previewer window, it is subject to a very strict CSP, where on the script tags, it is subject to nonce. So unless there is a way to leak nonce, we cannot embed a script tag. So what we did here is, we perform a meta redirect, which is a way to redirect to an external site within the Markdown. And once it redirects to our own site, it is not subject to that CSP policy. So we can run arbitrary JavaScript. We also use an attack known as XSLeak in order to leak the origin of where, for example, where this XSS execution was happening. And this leak provide us access to extension ID of VS Code. So if you have used VS Code, there are multiple extensions you can install. And these extensions come with their own unique identifier, which is a GUID string, which is not guessable. So we need to leak it. So we leak that in the step number one. And step number two, as we land on attacker.com website, we can get an XSS on the site. And this is the second protocol frame, which is VS Code web view. So there is an XSS vulnerability within the extension VS Code web view protocol frame. And we use this XSS to make another post message to the top layer of protocol frame, which is VS Code file. So we send a post message known as channel do read. And what this will give us a response is, it will give you the user directory where this project is running for. And this is important for the reliability of the project. Because you need to know where the user has downloaded it on their file system to perform further exploitation. So once you leak this user directory, what you can do is you can perform a redirection to VS Code file protocol, which works similar to file protocol. Like if you have used file etc password to read a file. But the catch here is this protocol can be invoked from any origin, unlike the traditional file protocol. So what we do is, we do an attack, which is VS Code hyphen file colon slash slash. And then we perform part reversal with dot dot slash and append this directory, which we have already leaked earlier in the previous step. And then we render an HTML page, which does stop dot require child process and get access to the node module. Because that is the window which is running with node integration too. So let's see how this exploit would look like in real world. So the victim has opened VS Code file, and now they will try to open our markdown. And as you can see, our calc is popped. And that is our demo for the VS Code remote code execution. So we received a bounty for $6,000 from Microsoft for this. And the main takeaway is that if you are a developer for an electron app, it is important to consider all your windows as a part of the threat model and apply the most restrictive settings on all of them, rather than just one of them or two of them. So let's switch gears a bit and increase the restrictiveness a bit more. So here we have context isolation is true. And as context isolation is enabled, node is not enabled. It is not directly available to the renderer. So we cannot use an exploit like the previous case where we just require a node library. So there are two ways to exploit this situation. So as you noticed here, sandbox is false. So we can use a Chrome V8 renderer exploit. So you can go to CRBug, find a crash proof of concept or a full blown Chrome end and run it. Or you can find a way to disable context isolation somehow. And that I will show you how we did. In the coming slides. So within our diagram, now we have two different separate context. XSS is on the application side and the node and electron API resides on the isolated context. So there is enough segregation at this point. So case study two, we will talk about Discord RC. So Discord was using electron version 12.14.1, which was an older version when we tested on the latest Discord version. But it also means that it is indirectly using an older version of Chrome, which is Chrome 83. We found XSS in one of the video embed in Discord. So if you have used Discord, when you chat with someone and you send them a YouTube link, it will expand and someone can click on that link and just watch it within Discord, the YouTube video, rather than going to the YouTube website. So we were looking for embeds to figure out what sort of vulnerable embeds we can find. And we were able to get XSS in Discord. In Vimeo, which is another famous video sharing service. And we exploit this XSS and perform our attack. But the problem here is that iframes or embed in electron are sandbox by default. So we cannot just simply run a V8 exploit and perform our exploitation. So what we did is we dig deeper into the Discord source code and we abused electron misconfiguration to open new window using window.open. And this new window was loaded with sandbox disabled. And now we can easily navigate to the attacker site and run our Chrome V8 exploit. So let's see Discord RCA. So the malicious actor is gonna send a URL to the victim and victim will try to interact with the URL. And as you can see a new window has opened. This is without sandbox. And we have this sandbox payload here which is going to pop a calc. So we were awarded around $5,000 bounty for this bug in Discord. And Discord fixed it by upgrading to the latest electron version. and also fix this new window opener bug so next time when it opens a window it will be open with a sandbox enable and most of you might be knowing about this issue of running a renderer exploit to exploit electron apps but what i'm showing you is that it is really common to have this in real world electron applications so for our next case we have a node integration to false sandbox is true in this case but this time the context isolation is false so as sandbox is true sandbox is enabled on the renderer process so we get the protection of chrome sandbox which uses seccomp on linux or win32k lockdown on windows so no node modules are exposed in the renderer because node integration is set to false but now as there is context isolation is disabled there is no isolation between the website you load an electrons internal or preload code and let's see what i mean by that so in the diagram here previously we had two separate contexts but now the electrons internal code preload and application all run within one single context so what can we do here because electrons internal code is running javascript as well so can we do something like prototype pollution and overwrite certain javascript function let's see so how to get a shell so if electron version less than 10 is used then you can use a prototype pollution gadget to leak remote or ipc module so according to electron documentation remote module is used to bridge javascript objects from the main process to the renderer process so when you leak a remote module even in a sandbox window you will get access to node primitives from electron version 10 to 14, developers thought that remote module is a very dangerous feature. So, they switch its default value to false. But developer can still go out of their way and enable it. So, you can do the same. You can use prototype pollution to leak remote or IPC. And most of the time remote module is disabled because developers do not do that in these common apps. So, you need to find some sort of IPC misconfiguration to leverage it to RCE. Let's look at the third case. So, electron version greater than 14, which are the newly electron versions. In this case, remote is completely deprecated. So, there is no feature called remote. But developers can still do an NPM install electrons slash remote to install it. But it is really uncommon to see that. So, what we do here is we leak IPC module. And our goal is to make sure that the remote module gets the same value as the IPC module. This is the to find an IPC misconfiguration within developer defined IPC channel like open URL which we saw or electrons internal IPC channel. So, this is the novel prototype pollution gadget we discovered for the latest electron version. And the concept of prototype pollution on context disable window was first proposed by Masato Kinugawa in 2018. But that exploit was working on the older electron version. And this one would work even on the latest one. So, what this exploit does it, I overwrite certain JavaScript inbuilt properties like ends with and call. And on number three, I get access to Webpack require which contains all this node electron modules which you can use to pop a calc in your favorite apps. So, for a situation where sandbox is false and context isolation is false, you may be wondering why not just run a V8 exploit. But with prototype pollution, with Webpack require, you get access to node primitives and you get access to electron common API which can be easily used to pop a calc. So, the benefit for using a prototype pollution compared to a V8 exploit is that here you don't require any binary exploitation skill. It is a complete web attack. The second one is it is more reliable compared to, for example, a V8 exploit which can be more of a heap. Massaging in certain cases. And the third one is what if the app which you are targeting is using a very latest electron version which doesn't have any chrome and within the patch gap. So, this will be helpful. But let's return to our original case where sandbox is true. Let's see what we can leak. So, in this case, we don't have access to node or electron common APIs like previously. But what we can do is we can leak electrons internal IPC bindings. For example, IPC renderer and IPC renderer internal. So, the IPC renderer is used to invoke developer defined channels. Whereas IPC renderer internal is used to invoke electrons internally defined channels. So, let's see how we use in a real world app. So, what I'm going to talk about is a local file read in Microsoft Teams which leads to account takeover. So, Microsoft Teams was using an electron version less than 15. Found an XSS using a zero day in CK editor which is used for rich text formatting. What we noticed is when you create a new window similar to Discord, context isolation is disabled and sandbox will be enabled. So, as context isolation is disabled, what we can do is run the prototype pollution gadget, leak the IPC using XSS. So, once we leak this IPC bindings, we not able to find any misconfiguration within developer-defined IPC in Microsoft Teams. But we were able to notice a misconfiguration in Electron's internal IPC. So, Electron has this IPC channel known as native image create thumbnail from path, which takes a path and reads that file and gives you an output. Think of it as a local file inclusion or local file read. So, what we were able to do is, in Microsoft Teams, we were able to read desktop config.json, which contains user-specific property, including the JWT token of the user. So, let's see how the expert would look like. So, here, the access is triggered. And as you can see on the attacker's website, they have access to desktop config.json. It is a bit small to read, but this is the content of the file, which contains the access token of the users. And with that, they can compromise the victim's Microsoft Teams account. So, we received $3,000 bounty from Microsoft for this issue. Let's move on to the last scenario, where everything is green. So, this type of app runs with the most secure settings, and it is used by most of the application. So, node integration is very easy to use. So, you cannot get node primitives directly on the web page. IPC cannot be leaked because context isolation is enabled, and it is fully sandboxed. So, to hack this is the main part of our research. So, in the diagram, we are right now in the sandbox renderer, and this is the most safest configuration possible in Electron today. So, at this point, you might be wondering that in this case, XSS in an Electron app would be the same as XSS in a browser. And the answer to that is no. The reason is that Electron apps are not same as your day-to-day use Chromium browser. Electron app is a combination of Electron native C++ code and Chromium code. So, can we somehow find a way to abuse this intersection between Chrome and Electron and subvert all the security features possible? Let's see. So, we move on to enabling node integration in subframes from a compromise renderer, which is a CV which was assigned to our findings. So, let's first talk about what is node integration in subframes. So, let's say you have a web page which is called example.com. And within this web page, you create multiple iframes to load another web page. Now, let's say if you want to provide this iframe access to node primitives or preload APIs, then how would you do it? The answer to that is, if you want to do this, enable a feature known as node integration in subframes. So, once you enable this feature, all your child windows or subframes will have access to node primitives or context bridge exposed API. So, for every subframe, if your parent page, example.com, has node integration enabled and sandbox disabled, then node JS primitives will be available within your iframes. If node integration is disabled and sandbox, it doesn't matter, enable or disable, then all your preload or context bridge exposed API will load within the iframe. So, let's take a look in the code to understand it a bit more. So, main process, here we have node integration in subframes set to false. Renderer process, we defined open URL channel, just like the first example. And this is our main window, which is google.com. What it does, it creates an iframe with a URL porn.af. And then it access window.electron.org. Open URL. Works fine. But when you try to access window.electron.open URL from the iframe, it's going to throw an error. Why? Because node integration in subframes is disabled. This case, let's turn it to true. And let's see what happens. So, here, iframe will have access to that context bridge exposed or preload APIs and is able to invoke it successfully. So, most of the time when we get accesses in all these apps, it is usually in embeds. So, for example, if you saw with Discord, we had an access in Vimeo embed. And in this case, a node integration in subframes is mostly disabled because developers, again, do not go out of their way to enable it. So, it's a bit sad because you don't now have access to context bridge exposed API. So, what can we do here? Can we still hack it? Let's see. So, let's take a deep dive into how node integration in subframes is enabled in Electron. So, Electron patches a blink web preference and adds security feature flags. For example, it implements node integration in subframes by patching this file. And this is the code where that entire logic of enabling and disabling a feature takes place. So, if you are able to read or not, there is a file which is under a directory known as shell slash renderer. It's a renderer folder. And this file contains a code which the area marked as red has something like a renderer frame where it gets access to blink web preferences and then access like a property which is node integration in subframes. And based on the value of it, one or zero, it's going to enable or disable it. So, if you are paying careful attention, you see that this feature and all these checks were implemented on the renderer side and not on the sandbox side. So, you can use a renderer Chrome exploit and set node integration in subframes to 1, then it should be able to enable it. So, let's look at an annotated version of our binary exploit. So, here on number 1 we get access to the web preferences offset in the memory. Then we add this static offset to get access to node integration in subframes. And then we overwrite its value to 1 from 0, which means enabling it. Let's see where in real world application we were able to find this. So Element is one of a commonly used texting app, and it was using Chrome 91 and Electron 13.5.1. We find an XSS on embed through a deep link misconfiguration. And as we had XSS on embed, no context bridge API was exposed to embed. So we run a Chrome renderer V8 exploit for Chrome 91 to expose context bridge API on embed. So this is the code of Element. Here, they define a channel on main.js known as user download open. And whatever the argument is passed, it goes inside a dangerous node.js function, which is shell.openpath. This is a dangerous thing for arbitrary code execution. On the other side, on the preload, it exposes a send method to the webpage in which you can pass any channel and argument to it. So as a diagram, let's go from sync to source. So main.js contains our RC sync. Preload.js contains send method. Your main website of Element has access to window.electron.send, but your XSS doesn't have access to that API. So with your exploit, what you can do is you can run a multi-stage exploit. For the stage one, you run V8 exploit and send node integration in subframes from zero to one. Which enables it. And on the stage two, you create an iframe within your first iframe, and this second iframe will load with node integration in subframe two, so it will have access to that send method, which you want to get that code execution. So this is the code version of the exploit, and I create an iframe within iframe after enabling node integration in subframe. So this will create another iframe, and that's gonna pop a calc. Let's see how it looks. Let's see what it looks like in the demo. Attacker is sending a URL to the victim. Victim is opening in the browser. They're gonna open in Element app. So it's a video conference. Everyone wants to join a video conference, so let's tap on join conference. And as you can see on the console, this is where our exploit is running behind the scene. It takes time to perform this heap massaging and calculating all this offset. And as you can see, we pop in the console. And we can see that we've got a lot of work to do. So let's go back to the calc. So we received $3,000 bug bounty from Internet Bug Bounty Program, and they fixed this entire electron-specific feature by not exposing this context bridge IPC to child renderer process. So if you do the same in the latest electron version, you won't be able to get access to window.exe. You'll be able to get access to window.exe and you'll be able to get access to window.exe within the iframe inside your iframe. So second, we move on to disabling context isolation, the most coveted feature of Electron.js from a compromised renderer. So same story, Electron defines that on the renderer side as well. In the code, we again go to shell slash renderer folder, which is a renderer side code, and it gets context underscore isolation variable in step one from Blink web preferences for a renderer. And then on the step two, it has a Boolean, which should create isolated context, which is based on the value from step number one. And at step three, there is a if statement. If it's true, then enable context isolation. If it's false, don't enable. So same story, use a V8 Chrome renderer exploit and set context underscore isolation from one to zero. So our annotated exploit would look the same as the previous one. We get access to context isolation in the memory, and then we overwrite to zero from one. So let's take a look at our final case study, where we found RC in an undisclosed app. This app was using Chrome 94 and Electron version 15, and it had a feature to embed untrusted content within iframe. So the code looks like this. On the right, we have the main.js, which defines the same open underscore external channel, which goes into dangerous node jsync. On the left, we have a preload.js, which implements a wrapper and has a function known as isAllowedUrl. This isAllowedUrl function will check whether a URL starts with a file protocol, which is HTTPS. So if we try to use a similar exploit as previous, it's not gonna work because we were passing like file path to calc.app. And in this case, file is the protocol, not HTTPS. So let's see what we can do here. So schematics again, if we try to run the node integration in subframe exploit, we have access to open external URL API, which was defined on the preload, but still it will be subjected to the HTTPS check. So how can we somehow directly make a call to the main process from our iframe? Let's see. So here is our exploit. On the stage one, we will run a V8 exploit to change, context isolation from one to zero, which means disabling context isolation. Then we perform a redirect after that step has happened. And we load a stage two, which is another page on your attacker website. And here we perform a prototype pollution attack, which I showed you in the earlier slide for CI-disabled windows. And this prototype pollution will leak you IPC bindings. And once you have access to this IPC binding, you can make. A direct call to the main process using IPC.send with that particular IPC. So here we are making a direct call to the main.js. So this is our exploit. This is how it looks in the code. So this is the disabling part. We redirect to leak.html. We perform our prototype pollution, and we do an IPC.send with two arguments within the first is channel, and the second is file part to calc. And the second is file part to calc. So let's see how our exploit would look like. So this is that famous undisclosed app running over exploit. So as you can see, it is calculating certain offsets, and then it is gonna perform the same thing, which we had in the previous example. So this will be its log. And as you can see, now we have access to that click me, which can pop a calc. So we received $5,000 bounty for this bug for this program. So now we will take a look into same site origin spoofing. So for example, this is your shiny new Electron app, and it is loading a webpage known as main.example.com. This webpage creates two iframes. The first one is youtube.com, and second one is sandbox.example.com. So let's see how the process are created within Electron apps. So it creates a separate process for youtube.com, but it uses the same process for main.example.com, for the sandbox.example.com. And this happens because Chrome has a feature known as site isolation, and site isolation doesn't apply when your top level domain are the same. So in this case, the common between the main and sandbox.example.com is the example.com top level domain. So Chrome uses the same process of both page. So in this case, if you are exploiting a real world app and you have XSS in sandbox, which is on the sandbox.example.com process, then what you can do is within a Chrome renderer via exploit, you can change document.url to main.example.com and security context origin port to 443. This way, you will be effectively able to masquerade to your parent window and are able to access all the context bridge exposed APIs or node primitives, which are available to the main window. So this is one way to do this. So let's talk about badge gap. So as we noticed in a lot of this real world applications, we have used Chrome via trender or exploit. You might be wondering, is it really very light? Is it likely to use a V8 exploit in all this real world app? And the answer is yes. And this stems from the fact that there is a noticeable badge gap between Chrome, Electron, and Electron applications, which makes most of them susceptible to this attack. And an adversary or an attacker can also go one step further and can use sandbox as for Chrome. But here, which I showed, even with a renderer exploit, you can do a lot of stuff and just defeat the entire, uh, ElectronJS security features. So let's talk about the mitigations. So for the developers, um, I would suggest that enable all the security features, because a lot of these bugs, which we submitted to ElectronJS frameworks, were fixed promptly by it. But there is a design flaw which is present in the ElectronJS framework, which allows you to access these, um, features from a renderer process. So this flaw is currently still present. So even with Renderer Expert today, you can disable context isolation, for example. But Electron.js, our developers have took enough steps to not expose APIs, for example, in node integration in subframes, which prevents a few of our exploits here. So if you are using an app, make sure to upgrade your Electron version very regularly. So if you are a developer who is always keeping up with the pace of this Electron releases, then you should be pretty much safe for this patch gap, and it would be narrow. And if you have an organization who can maintain your own fork of Electron, you can cherry pick this V8 fixes and can deploy that to be one step further. So another important aspect is to don't use a third-party embeds on your website. We saw that a failure point with Discord was to use Vimeo embeds. For example, here. So make sure that you use pretty trusted embeds. And even if you use, make sure you have enough defense in depth, because that embed can lead to a code execution in your own app. So be careful about that. And the last suggestion here is to mitigate vulnerabilities across all your assets. So even if you have subdomains, as we saw that you can use an XSS on subdomain and then just go back to the main window using the same site. Exploit. So that should be the part of our mitigations. So as a part of our epilogue, what I want to mention is we were able to compromise 20 different Electron applications. These are used by millions of people. And some of the examples which I didn't show in the talk are JupyterLab, Mattermost, Basecamp, Notion, Rocket Chat, and others. So for our takeaways as a part of this talk, I want to mention that we are able to compromise 20 different Electron applications. to emphasize on three key points the first one is related to bug bounty hunters and security researcher and it is to dig deeper into the framework which you are auditing and to not limit yourself to the application layer so in our research we didn't stop on just the javascript side of the things on electron but we took a look into how these features were implemented and what are the possibilities to tamper with those so go as deep as possible when you are auditing this sort of frameworks the second one is electron apps are a very ideal adversarial or red team target as you can see all this app discord element you just send a link and it just requires single click and some of our exploit even doesn't require a click and you can gain a system level shell on the operating system so users are going to open the link they are going to open the link and they to join conferences and they are going to click on certain stuff so this is really important and if you are on the detection team or blue team it is important to also consider electrons app as a part of your threat model and see it as the same entry point as any other asset you have in your organization the third one if if you are a developer minimize attack surface on your application as much as possible so electron is not bad i would say if you are implementing and doing all the best practices it is it is still going to provide you and guarantee you security features but you need to work towards that you need to minimize this attack surface so a good example to this is a textbook low level attack known as open url redirection which is a p5 on a lot of bounty program in electron app if you find a open url redirection you can redirect to your own website and you have control to the window and then you can just run this electron exploit to gain in RC. So who knows, some days open, sometime open URL redirection in your app can lead to RC. So please pay careful attention to your assets as well. So at the end of this, I would like to thank everyone for coming and viewing our talk and for your attention, time, and interest. And if you want to understand in details about our findings, we have created a website, which is electroworld.io. And within this website, there is a menu for blog, which opens blog.electroworld.io. And there you can find proof of concept and this exploit code for the use cases, which I mentioned here. And we will be also updating this site time to time to include all the 20 use cases and ElectronJ specific flaws. So with that, I conclude my presentation here. And thanks again for coming to see Electroworld. Thank you very much.