-
Notifications
You must be signed in to change notification settings - Fork 67
Implement Electron security guidelines #129
Conversation
"3. Enable context isolation in all renderers that display remote content" needs some explanation (for future reference). TL;DR There are some gymnastics to do in order to have Parity UI follow all these guidelines. Without // In inject.js
window.ethereum = ...;
// In dapp
console.log(window.ethereum); // Will print something With // In inject.js
window.ethereum = ...;
// In dapp
console.log(window.ethereum); // undefined, because preload and dapp do not share context
// Also, dapp cannot send IPC message to shell anymore (due to no nodeintegration)
Solution
Because the shell can't communicate with the dapp via postMessage nor IPC. But the shell can communicate with preload.js via IPC, and the dapp can communicate with preload.js via postMessage. So preload.js acts as a message relayer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks sane, it feels sane when running - however worried that there may be edge-cases I have not seen with "doing some dapp stuff" testing.
It would be good to get a bit wider testing with binaries.
electron/index.js
Outdated
// https://electronjs.org/docs/tutorial/security#4-handle-session-permission-requests-from-remote-content | ||
session.defaultSession | ||
.setPermissionRequestHandler((webContents, permission, callback) => { | ||
if (!url.startsWith('file:')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
url
refers to the library here. You forgot: const url = webContents.getURL()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
F*ck... Nice catch, thanks!
}); | ||
|
||
// Load inject.js as a string, and inject it into the webview with executeJavaScript | ||
fs.readFile(path.join(remote.getGlobal('dirName'), '..', '.build', 'inject.js'), 'utf8', (err, injectFile) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we use getBuildPath()
from src/util/host.js
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately not, I was getting a window.require
is not a function.
Reason is: in preload.js, isElectron()
is true, however it's not a renderer process so you would do require('electron')
instead of window.require('electron')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be working fine! HoweverParity/Web3 console
dapp (tried on kovan) doesn't seem to work anymore: Error: Sorry, this app does not support window.eval().
Electron has a 12-point checklist called "Security, Native Capabilities, and Your Responsibility". Parity UI should follow those guidelines.
eval()
. However all networks dapps disallow eval() in their CSP, so we actually don't need this.Also removing the proxy to
/parity-utils
, so that the onlyinject.js
the dapps are receiving now is the one injected by Electron.