-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Secure our Electron implementation #7567
Conversation
Hey, I noticed you changed some webpack configuration files. This can break production builds. Did you remember to run a production build locally to verify they still work? |
@@ -146,8 +146,4 @@ const webpackConfig = { | |||
}, | |||
}; | |||
|
|||
if (platform === 'desktop') { | |||
webpackConfig.target = 'electron-renderer'; |
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.
This is no longer needed – because we're using context isolation, the renderer process (our app that's bundled by webpack) is just like a regular web app without any direct access to Electron or Node APIs, except those defined in the contextBridge
@@ -145,7 +141,8 @@ const mainWindow = (() => { | |||
width: 1200, | |||
height: 900, | |||
webPreferences: { | |||
nodeIntegration: true, | |||
preload: `${__dirname}/contextBridge.js`, |
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.
These lines right here are the most significant changes
// make sure local urls stay in electron perimeter | ||
if (url.substr(0, 'file://'.length) === 'file://') { | ||
return; | ||
browserWindow.webContents.setWindowOpenHandler(({url}) => { |
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.
The new-window
event was deprecated and replaced by this setWindowOpenHandler
API in Electron 12.
const denial = {action: 'deny'}; | ||
|
||
// Make sure local urls stay in electron perimeter | ||
if (url.substr(0, 'file://'.length).toLowerCase() === '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.
Note: it used to be possible to open apps and files (bypassing the blacklist we had here), simply by using a URL like File://
or 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.
Ooh nice changes!
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.
The tests work well and these look like good changes based on the Electron recommendations.
Is merging blocked on this remaining todo? Enable sandbox mode ? |
Nope. We can address that in a follow-up. |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by @AndrewGable in version: 1.1.38-0 🚀
|
🚀 Deployed to production by @Julesssss in version: 1.1.38-3 🚀
|
Details
This PR implements many of the security best practices outlined in Electron's documentation. There is a lot of context behind why these changes are a good idea, but this is one of the best resources I've found with a good summary: https://github.com/reZach/secure-electron-template/blob/master/docs/newtoelectron.md.
TL;DR we're completely separating the website code (renderer process) from the powerful Node.js and Electron API's, and any communication between the renderer and main processes (which can use those APIs) has to happen through whitelisted channels. There's also some additional context in https://github.com/Expensify/Expensify/issues/193886
Fun fact: A random side-effect of this PR is that if you run
npm run desktop
, you can also view the renderer process of the desktop app in your browser by going to localhost:PORT. This is almost the same as runningnpm run web
, with the exception ofindex.desktop.js
files will be used instead ofindex.website.js
.Remaining TODOS:
Fixed Issues
$ https://github.com/Expensify/Expensify/issues/193886
$ https://github.com/Expensify/Expensify/issues/166153
Tests / QA steps.
View Keyboard Shortcuts
. Verify the keyboard shortcuts modal opens. This verifies that events from the main process are being sent to the renderer process correctly.Tested On
Screenshots
Desktop
Successful local production build