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.
What is an easy way to write a browser application on Linux (Crunchbang/Debian)?
I need to write an application for some DOM editing and automation. My preferred way of doing this is to have my own browser object (like WebKit's WebView or System.Windows.Forms.WebBrowser) and access the DOM from there. I tried both (with mono), but I found two things:
WebView does not implement DOM access (ref)
System.Windows.Forms.WebBrowser does not work (ref)
This means Mono is not very suitable for this purpose.
What is your preferred way for accessing web pages, reading the DOM and automating navigation?
Probably easier to use PhantomJS?
Uses Webkit to render webpages and then makes the DOM available for you:
http://phantomjs.org
I know its a security feature in IE to not allow scripts to interact past frame tags/objects but is there a way around this?
I am using a program to interact with the IE COM interface.
For example if I were to have an tag and I wanted to use the $tagobject.innerhtml to retrieve the html inside the frame tag, what is the best way of going that this?
Native code running at full trust (e.g. an IE plugin) can interact with any document loaded in the browser. You're correct to note that interacting with subframes that are from an origin different than the top-level page is blocked by security policy when accessed in the "simple" way. But native code can circumvent that.
This support article shows how to enumerate the contents of all frames, regardless of their origin. The basic idea is that you cast the top-level document to an IOleContainer and then enumerate its children, which bypasses the security check.
I need a way to "disable JavaScript" / "not run JavaScript" in the web browser.
Is it possible to do it using JavaScript or some other automatic way?
Update: reason for this? Easy, there are some "online TV sites" where they use several iframes pointing to "cross site urls" and it is annoying to get several "advertising" pop ups all the time. By coding my own webbrowser "add-on/extension" I've tried to "delete" html nodes and some Javascript and it works for the "main page" code, not for iframe "Cross Domain URL".... so I think disabling javascript AFTER the movie starts, would be a nice solution.
Update 2:
The video I want is a result of a iframe cascade chain.... I've tried all the way to "catch" the final "url" result using fiddler and other tools, but its getting hard since this different "cross domain" communication is sharing "runtime keys" to avoid what I want to accomplish (perhaps with more time I can do it) but this is why I thought that an easy and fast solution would be just disable javascript after the movie starts.
NOTE: other extensions such as Adblock and similars DO NOT work, since the website detect it and the video never loads.
No, it is not possible to programmatically disable the JavaScript on a user's browser using another JavaScript add-on/extension.
However, it may be possible if you use PHP as a proxy to intercept the pages you want, and strip out all script tags. You might even be able to extract the video URL you want and play it using another (flash?) player.
If you are a system administrator and want to disable JavaScript on all your network's computers, please post on SuperUser instead.
You can't disable, but you can overwrite the javascript functions.
alert = function(){}
alert("hello")
You can even kill those iframes by tag name.
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.