Bad Practice 101
Tldr
It is sometimes helpful to know what not to do. Just so we're clear: don't do this! ;)
This is only to show how easy it is for any JavaScript code running in the renderer process to behave
like a full-blown Node.js program including access to Node.js require
and its native APIs.
We have also disabled context isolation meaning that any script (including third-party script) can also manipulate the page and its data (e.g. cookies).
If your app gets compromised (e.g. XSS, rogue third-party dependency, etc.) the potential for damage is huge.
Main Process
We have enabled the node integration and disabled context isolation:
const {app, BrowserWindow} = require('electron');
app.whenReady().then(async () => {
const bwin = new BrowserWindow({
width: 300,
height: 300,
webPreferences: {
nodeIntegration: true, // <- Don't do this!
contextIsolation: false // <- Don't do this!
}
});
await bwin.loadFile('renderer.html');
bwin.show();
});
Renderer Page
We import a script into the page. Third-party scripts will run with the exact same privileges.
<html>
<head>
<style>
body {background-color:black;color:limegreen}
</style>
</head>
<body>
<pre></pre>
<script src="./renderer.js"></script>
</body>
</html>
Renderer Script
Because node integration is enabled this script has access to the Node.js APIs. We can see that this script is attempting to read a file that was meant to remain secret.
Also since the context isolation is disabled this script is sharing the same context execution as the renderer page so can directly modify the DOM and/or read cookies.
const fs = require('fs');
const path = require('path');
const secret = fs.readFileSync(path.join(__dirname, 'secret.txt'));
document.querySelector('pre').innerHTML = secret;