Skip to content
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

Security: Make the man-in-the-middle in the webextension optional #94

Open
minfrin opened this issue Oct 2, 2021 · 0 comments
Open

Comments

@minfrin
Copy link

minfrin commented Oct 2, 2021

Right now, there are two men-in-the-middle between a webpage and a webextension native app:

  • The content script; or optionally on Chrome
  • An external website limited to the top two levels of a domain name.

It must be possible for a webpage and a background script of an extension to be communicated with without a content script being present, and without being limited to an explicit external set of websites.

content script

In order for a webpage to contact a webextension's native app via a content script, the communication flow is as follows:

webpage -[1]-> content-script -[2]-> background-script -[3]-> native-app.

Starting from the back:

[3] The native app sends messages to the background script over stdin/stdout (or API call for Safari). There is no man in the middle possible here.

[2] The background script is sent messages by the content script using browser.runtime.connect(). The content script in some cases can contact any background script, and there is no strong verification whether the name has been faked, thus a potential man-in-the-middle and #76. In other cases (Safari, to my knowledge) the content script can only contact it's own background script, meaning that man in the middle is prevented. The content script however has "root" access to the webpage, and so has the same security level as an old Netscape plugin.

[1] The webpage sends messages to either all contact scripts of all extensions with document.dispatchEvent(), or to all open tabs with window.postMessage(). Here all extensions are a potential man-in-the-middle, or all open tabs are men-in-the-middle, thus #78

external website

On Chrome, In order for a webpage to contact a webextension's native app via an external website, the communication flow is as follows:

webpage -[1]-> webextension-owner-webpage -[2]-> background-script -[3]-> native-app

Starting from the back:

[3] The native app is contacted by the background script over stdin/stdout (or API call for Safari). There is no man in the middle possible here.

[2] The background script is contacted by the webextension-owner-webpage using chrome.runtime.connect() and externally_connectable. The externally_connectable option only works if a man-in-the-middle website is specified as a subdomain of https://publicsuffix.org/list/. Extensions wishing to be general purpose and work on all websites are forced to introduce the men-in-the-middle as specified above under "content script".

[1] The webpage is forced to pass information across to a website controlled by the extension owner., the webextension-owner-webpage is the man in the middle.

fixing the problem

The simplest fix for the problem is to standardise externally_connectable while lifting the restriction that 'Patterns cannot include wildcard domains nor subdomains of (effective) top level domains;'.

This makes no changes to the existing ecosystem and all existing plugins will still work, and allows a webextension to offer services to everyone without a man-in-the-middle.

To strengthen this, we need to add #76 so that the end user can be protected from bogus extensions.

At the same time, dangerous practices like #78 need to be actively removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant