I asked this question a little over a week ago on the Atom forums (link below), and didn't receive a response, so I am reposting it here in the hopes that someone may be able to provide insight on my problem.
Recently, I have taken up an open source project which uses Electron as it’s front-end. This project has two requirements: it must be cross-platform, and it must have an embedded web browser (which should be able to browse the web and render content like a typical browser). Considering the rather large footprint Electron has already netted my application, it seems like a bad idea to attempt to use another embedded web framework alongside it. So, in the interest of simplifying my project and retaining the UI built on top of Electron, I am looking into using Electron itself as the web browser. Here’s where I’ve come into a problem.
In a security page for Electron’s documentation, it is explicitly stated that,
it is important to understand … Electron is not a web browser
This quote comes within the context that Electron–or rather the code running on top of it–carries the unique ability to interact with the user’s operating system, unlike typical web applications. The page goes on to say,
displaying arbitrary content from untrusted sources poses a severe security risk that Electron is not intended to handle
At this point, I was tempted to give up on the idea of using Electron as an inbuilt browser, but further down on that same page, you can find another very interesting tidbit:
To display remote content, use the <webview> tag or BrowserView , [and] make sure to disable the nodeIntegration and enable contextIsolation
Link: https://electronjs.org/docs/tutorial/security#isolation-for-untrusted-content
First, in regard to using webviews, Electron’s own documentation recommends outright avoiding them:
Electron’s webview tag is based on Chromium’s webview , which is undergoing dramatic architectural changes. This impacts the stability of webviews , including rendering, navigation, and event routing. We currently recommend to not use the webview tag and to consider alternatives, like iframe , Electron’s BrowserView , or an architecture that avoids embedded content altogether.
Link: https://electronjs.org/docs/api/webview-tag
Seeing as though I cannot avoid embedded content, I opted to look into using a BrowserView, but what I found was not very motivating either. The advice, as it stands, is to do two things:
disable nodeIntegration
enable contextIsolation
After looking at the security and best-practices page, I will also append the following steps:
deny session permission requests from remote content (webcam, microphone, location, etc.)
catch webview elements in creation and strip default privileges
disable the creation of new windows
disable the remote module
That is a fair amount of steps to undergo in securing external content. Not to mention, there were several additional warnings scattered through the best practices page such as the following:
(On verifying webview options before creation)
Again, this list merely minimizes the risk, it does not remove it. If your goal is to display a website, a browser will be a more secure option.
Link: https://electronjs.org/docs/tutorial/security#11-verify-webview-options-before-creation
(On disabling the remote module)
However, if your app can run untrusted content and even if you sandbox your renderer processes accordingly, the remote module makes it easy for malicious code to escape the sandbox and have access to system resources via the higher privileges of the main process.
Link: https://electronjs.org/docs/tutorial/security#15-disable-the-remote-module
Not to mention, upon navigation to the BrowserView page, the whole class is listed as experimental.
This all isn’t even to mention the added attack surface created by Electron, such as a vulnerability in the webview component just last year: CVE-2018-1000136
Now, taking into account all of the above, numerous developers have still opted to create web browsers that routinely consume external and uncontrolled content using Electron.
Browser’s using Electron (linked directly from Electron’s website):
https://electronjs.org/apps/wexond
https://electronjs.org/apps/dot
https://electronjs.org/apps/beaker-browser
To me, it seems irresponsible to submit users to the above security implications as a trade-off for convenience.
That being said, my question is: can you safely, to the point at which you could ensure the integrity of your users, implement web browsing capabilities for uncontrolled content using Electron?
Thank you for your time.
Link to the original post:
https://discuss.atom.io/t/security-implications-in-electron-as-a-web-browser/70653
Some ideas that don't fit into a comment box:
[the project] must have an embedded web browser
So I presume then that this project isn't just a web browser. There's other content there that may have access to Node, but you just want the embedded-web-browser portion of it to be sandboxed appropriately, right?
Regarding the comments about <webview>, yes, it is considered unstable and Electron recommends using a BrowserView instead. I don't think that the fact that it's marked as "experimental" should necessarily deter you from using it (especially considering that the Electron team is recommending it [though maybe as the best of two evils]).
Experimental doesn't imply it's unstable. It can just mean that the Electron team is experimenting with this approach, but this approach may change in the future (at which point I would expect Electron to provide a transition path forward). Though this is one possible interpretation and ultimately Electron would have to comment on this.
The advice... is to do two things:
disable nodeIntegration
enable contextIsolation
I would also make use of the sandbox option inherited from BrowserWindows. BrowserView's docs on the constructor options say:
webPreferences Object (optional) - See BrowserWindow.
which tells me that BrowserView accepts the same options as BrowserWindow.
You would set it up like so:
new BrowserView({ webPreferences: {
sandbox: true,
nodeIntegration: false,
contextIsolation: true,
preload: "./pathToPreloadScript.js"
}});
See more information about this approach here. The preload script is what would expose some Node IPC APIs to the sandboxed content you're loading. Note the Status section at the bottom, which says:
Please use the sandbox option with care, as it is still an experimental feature. We are still not aware of the security implications of exposing some Electron renderer APIs to the preload script
If the content you're loading in the BrowserView never needs to communicate back to the application, then you don't need a preload script at all and can just sandbox the BrowserView.
After looking at the security and best-practices page, I will also append the following steps:
deny session permission requests from remote content (webcam, microphone, location, etc.)
catch webview elements in creation and strip default privileges
disable the creation of new windows
disable the remote module
Sure, those sound reasonable. Note that if your embedded browser needs to be able to open new windows (via window.open or <a target="_blank" />) then you'd have to allow popups.
That is a fair amount of steps to undergo in securing external content.
Sure, but is your main concern with the security of the app, or with how much work it takes to make it secure? Browser developers need to consider similar things to ensure webpages can't get access to the OS. It's just part of the game.
Again, this list merely minimizes the risk, it does not remove it. If your goal is to display a website, a browser will be a more secure option.
This is just saying that if all you're trying to do is display a website, then just use a browser since that's what they're there for.
If you need to do other things, well then you can't use a browser, so you'll have to make your own app, making sure it's reasonably secure.
I think that if you follow what's recommended in the Security document and keep up to date with new Electron releases, then you're doing the best you can do.
As for whether that's good enough, I can't say. It depends on what you're developing and what you're trying to protect against.
However, my thoughts can't substitute the more expert opinions of those on the Electron team. This question could certainly use some guidance from them.
For security considerations I am wondering if Chrome extensions had access to an app. I design a Chrome App which handles sensitive data. As far as I understand it, that app runs in a sandboxed environment which should be fairly isolated. If a user had by mistake installed a malicious Chrome extension, would that extension be able to intercept/modify any of the sensitive data in the app?
Please note that I do not consider other ways of interceptions outside of the Chrome environment, e.g. some virus that allows someone to get root access or alike. I would just like to understand to what degree a Chrome app is more susceptible to interception than a standard stand-alone application.
Sebastian
On one hand, extensions cannot touch your app's windows (as in, inspection / script injection) in the default environment, even with "debugger" permission. Your "local" data should be safe.
On the other, I tested it and conclude that webRequest API will catch all XHRs you send.
This includes headers for both request and response, and request body. Response body is currently not available for inspection; however, a malicious extension can perform a redirect, modify your request or cancel it.
This was deemed a security issue; as of Chrome 45, extensions can no longer intercept traffic from other extensions and apps. Hosted apps were accidentally included too, but it's a bug that will be fixed soon - traffic from hosted apps will be open to webRequest as normal.
I don't know any other possibility for an extension to snoop on an app (without any anomalous chrome://flag configuration).
Extensions or other apps cannot access data inside other extensions or apps. An exception may be data in the syncFileSystem api, since an extension could be granted access to the user's Gdrive.
Is there an API for a Chrome extension to launch and control new Chrome windows under different user profiles?
My understanding is that while an extension may be run under multiple user profiles simultaneously, these instances are isolated; they cannot communicate directly and an extension in one profile cannot access the windows/tabs/processes/etc of another profile. Is this the case?
It seems like the best way to launch and control Chrome windows under multiple profiles is to use an approach based on the Remote Debugger API such as the ChromeDriver project.
For context, I'm interested in writing a tool to manage and launch predefined "bundles" of multiple Chrome windows, each with different URLs and screen positions, and each under a different profiles. The attached screenshot shows an example desired state: three browsers, each in a separate profile, each at a different URL, with different devtools states, organized in a specific screen layout. It is conceptually similar to tmuxinator.
If I wanted to provide a Chrome-based UI for designing and managing these presaved layouts, it seems that I would need to provide a native shim that invokes new Chromes via chromedriver, and communicate with them via native messaging. Is there a more direct API that I am missing?
It seems that the proposed Profile Extension API would do exactly what I'm interested in, but I don't see any discussion on the apps-dev#chromium.org list.
If chrome allowed this it would be a huge security hole.
Chrome extensions are installed per user account so they shouldnt be able to see anything from other accounts.
I am developing a chrome extension/app that requires
communicate with Intranet services in UDP binary protocol using chrome.socket APIs
need to extract DOM content from non-app web pages. This could be done using bookmarklet, Browser Actions, page actions, or chrome context menus.
There are two chrome.contextMenus APIs
http://developer.chrome.com/apps/contextMenus.html
http://developer.chrome.com/extensions/contextMenus.html
One for Packaged App, another for Extensions. The former only insert contextMenus to Packages Apps, not normal web pages.
If I need both chrome.socket & invoking from normal webpage capability, do I need to create both an extension as well as an app? That would be very confusing to end users.
Yes, you need both the app and the extension. Apps are intentionally devoid of APIs that modify web pages. That's where extensions come in.
I ran into the same problem and had to make two separate apps for exactly the same reasons. (JSTorrent contextmenu extension && JSTorrent).
I believe there are ways to trigger the install dialog from one to the other, but I have not tried to do this yet. If somebody had examples for how to do this, that would be great to add here!
Consider using <webview> in an app. You'll be able to display web content there, and you can more easily communicate between the app and the content. It will result in a single installable item.
Is there any good reason why I can't use two of them together?
browser_action
page_action
app
I can't think why single extension can't use browser and page specific actions together. Why should I have to write single extension for each action ...
For a browser that boasts about its simplicity I believe that is the clearest explanation. To prevent clutter.
Packaged Apps is the easiest to explain as they are basically an alternative to Hosted Apps for developers that don't wish to host a service or wish to make their app fully integrated in to Chrome and/or work offline. However, since packaged apps are bundled as extensions this prevents them from adding anything to the browser's chrome since hosted apps don't have this ability.
Regarding the action choice, I can only imagine this restriction is to help prevent extensions from overcrowding the address bar and the toolbar with duplication.
In a lot of cases using badges and the onClicked event correctly can replicate a lot of the functionality of page actions in browser actions while using a combination of content scripts and message passing to trigger changes.
The StumbleUpon extension rotates its browser action's behavior depending on whether or not its toolbar is currently displaying.