Security Implications in Electron as a Web Browser - node.js

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.

Related

Inline install doesn't work on new extension

Does anybody have the same problem? New extension with verified domain and enabled inline install after clicking on button with chrome.webstore.install();cause redirect to chromestore with get parameter ?utm_source=inline-install-disabled
I recently received the following email from Chrome Web Store Developer Support:
In addition to the existing extension-level protection, our expanded
enforcement will also use machine learning to evaluate each inline
installation request for signals of deceptive, confusing, or malicious
ads or webpages. When we find those signals, we'll selectively disable
that one inline installation request and redirect the user to the
extension's page on the Chrome Web Store. This selective enforcement
will not impact inline installation of that extension from other,
non-deceptive sources. Developers will not be notified of this
enforcement, as it happens on an as-needed basis.
Are you serving any ads on your site or doing anything else that might be perceived as a grey area by ML?
If you're being blatantly deceptive, it would appear that you've been found out. If not, and you're genuinely confused, a possible first step would be to scrape your site of any ads or injected content altogether to see if you're able to regain Google's trust.

Tabs/Windows in Chrome apps

It appears that chrome apps are unable to render as tabs in the browser... I happen to like the chrome tabbing interface and it would be a shame to have to try and re-implement it in html/css/js. Is there really no way to do tab management at the chrome application level? Must all new windows be shell/panel level windows?
I can imagine scenarios for applications where they would want to contribute extension related features to the browser... why are you making it more confusing for users (who now have to install an app and an extension) in order to get the full feature set?
Is there really no room for middle-ground here?
Chrome apps are separate from the browser. This is a very deliberate approach, which is unlikely to change.
For apps to be seen as apps, as opposed to websites, which are always available regardless of connectivity, they need to be seen as separate to a browser. We have found having apps launched and run outside the browser very important for users to conceptualize them as apps.
There are also security reasons to keep apps out of the browser. They have access to APIs that websites and extensions do not have access to, but to make this possible they are also individually sandboxed and have no access to the browser.
Extensions and apps can communicate via messages. It is less than ideal that a user may need to install both an app and an extension; we have been looking at some form of bundling to make this simpler.

For google chrome extension development, is it possible to set a download location?

As the question says, can an extension save files to a user-set location for all future downloads (that differs from the download location set in preferences)?
If so, how would this be done?
Thanks
See this issue for a lengthy discussion on the matter. Per the last qualitative entry on 8.10.2012:
The downloads ui is a very sensitive part of chrome from a security
perspective, so it is unlikely that we will ever be able to allow
extensions to completely replace chrome's downloads ui. We have plans
to allow extensions to extend chrome://downloads in a limited and
safe way, and extensions may add browser action buttons, but
replacing the downloads ui entirely is not likely in the foreseeable
future. Witness the search engine hijacking security issues. With the
--disable-downloads-shelf flag, extensions could suggest that users set that flag.
Please also feel free to write a download manager extension as a
browser action to demonstrate a better ui. If a download manager
extension gains sufficient popularity, we may consider adopting
something like it as chrome's native downloads ui. That's a more
likely way that extensions could replace the ui, but slower and safer.
My guess is that you can't. It would be a security issue if plugins had such abilities.

Why I cannot use two or more "browser_action", "page_action" or "app" together?

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.

Always using google chrome frame meta tag for standard compliant page, is good idea?

I was thinking to add meta tag always in all the websites.
That will trigger google chorme frame to load for users who already installed. I can see the benefits but is there any concerns or facts that I should know before I do that?
Testing in google chrome is enough or testing in google chrome frame explicitly required?
Thanks
Note: please do not mention current know problems "print" and "download" issue. I'm sure those will get fixed soon :)
The only argument against chrome frame that I have seen so far is Microsoft's - "Google Chrome Frame running as a plugin has doubled the attach area for malware and malicious scripts."
Also, you may run into problems with frames. If you have chrome frame on your page and someone has that page iframed on their site you may run into some problems. More info:
http://groups.google.com/group/google-chrome-frame/browse_thread/thread/d5ffe442658bc60e/e6d7a4c1c179c931?lnk=gst&q=iframe
You should only need to test in Chrome Frame for (X)HTML, CSS, and JavaScript...basic stuff. If you are using AJAX (while trying not to break the back button), worried about caching, cookies (accessed via javascript), or other potentially browser-specific browser interactions I suggest testing on the IE+CF platform...at least until the CF team announces 100% interoperability between CF and IE.
Check out the CF Google group for more issues.
Are there any concerns or facts you should know? Yes: Not everyone has Google Chrome Frame installed.
You are adding a new user agent that you will need to test and debug against, without removing the need to test and debug the user experience for other browsers (notably plain IE by itself).
If you don't make the IE user experience equivalent to the Google Chrome experience, then you are alienating a significant percentage of users. Depending on your website and its expected users, the impact of this may range from undesirable to unacceptable. If you do make the user experience equivalent, then there is no point in adding the meta tag.

Resources