WebExtensions/Native Messaging

From MozillaWiki
Jump to: navigation, search

This page is about the project to add APIs related to native messaging to WebExtensions. The APIs will be based on the native messaging APIs from Chrome. The overall tracking bug for this project is bug 1190682.

Testing

If you want to use native messaging, then you'll need some documentation and learn how to write an add-on using runtime.connectNative.

You'll need to know where to write the manifest files and that's contained below.

Overview of native messaging

Native messaging enables communication between an extension and native applications running on the same host as the browser. A typical user of these APIs is password managers (e.g., 1Password, LastPass) in which much of the storage and encryption logic for a password database is part of a native application but a companion browser extension is used to automatically fill out web forms. For many reasons, authors of these applications prefer to keep the core code for these applications in native applications and maintain a relatively small extension that handles browser-specific features and communicates with the native application to actually get at the product's main functionality. Without a native messaging API, extension developers have used NPAPI-based plugins to communicate with native applications. But with the imminent removal of NPAPI, native messaging is crucial to ensure that we have a dependable and supported solution for these applications.

Extensions that use native messaging are installed just like any other extension. The actual native applications, however, are not installed or managed by the browser, they are installed using the underlying operating system's facilities (including notably, security and permission checking). Extensions and native applications come together via a "host manifest file". This is a short JSON file that includes:

  • A name, used by the extension (in methods like connectNative() to identify the native application it wants to communicate with.
  • The filesystem path to the executable for the native application.
  • A list of extensions that are allowed to communicate with this application.

The host manifest file must be installed along with the native application. That is, the browser reads and validates host manifest files but it does not install or manage them -- the security model for when and how these files are installed/updated/etc is much more similar to installing native applications than installing or configuring extensions. A section below includes much more detail about the specific contents of host manifest files.

The actual communication channel between the browser and a native application is a pipe from the browser that is connected to stdin/stdout in the native application. Note that this means that the native application must be launched by the browser. The Chrome host manifest format has a "type" property that allows other methods to be added in the future, though the pipe method is the only one that has existed since this feature was introduced in 2013.

Design for Firefox native messaging

subprocess

All the work of launching a child process and doing I/O is contained in a toolkit module called "subprocess", which is loosely based on the existing child_process addon SDK module but with a narrower interface and written from scratch with an emphasis on performance with large messages.

Host Manifests

The documentation for Chrome host manifest files is here. Although these files are small, they present some important design decisions around cross-browser compatibility. It is clear that as currently specified, we can't be directly compatible with Chrome for two reasons:

  • The locations where manifests are found use filesystem paths and registry keys that are very clearly specific to Chrome.
  • The "allowed_origins" property of the manifest includes origins of the form "chrome-extension://<chrome extension id>", these are obviously not meaningful in Firefox.

So, we can create a specification that is similar but not identical to Chrome's. Here is a proposal:

The host manifest file will contain:

 {
   "name": "com.my_company.my_application",
   "description": "My Application",
   "path": "C:\\Program Files\\My Application\\chrome_native_messaging_host.exe",
   "type": "stdio",
   "allowed_extensions": [ "myextension@mycompany.com" ]
 }

This is mostly the same as the current Chrome format with the exception of the "allowed_extensions" field which replaces "allowed_origins" from the Chrome manifest. Instead of using origins (which would run into the same issue outlined in bug 1257989), we will just use a list of extension ids that are allowed to use this application.

Locations of the manifest files will be:

Platform Type Location
Windows Global Path contained in registry key HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\NativeMessagingHosts\<name>
Windows User Path contained in registry key HKEY_CURRENT_USER\Software\Mozilla\NativeMessagingHosts\<name>
Mac Global /Library/Application Support/Mozilla/NativeMessagingHosts/<name>.json
Mac User ~/Library/Application Support/Mozilla/NativeMessagingHosts/<name>.json
Linux Global /usr/{lib,lib64,share}/mozilla/native-messaging-hosts/<name>.json
Linux User ~/.mozilla/native-messaging-hosts/<name>.json

In the longer term, it would be valuable have a standardized approach to native messaging that works across browsers without any changes. The appropriate place to design a cross-browser standard is the W3C browserext working group. At the least, designing a cross-browser standard for native messaging would require designing a cross-browser standard for extension identifiers, to be used for permissions checks. This is a laudable goal, but one that is likely to some time. This leaves us with a choice between waiting for that standard implementing the above proposal right now and then adding support for the new standard when it emerges while remaining compatible with the Firefox-specific specification. The latter is obviously undesirable but not so much that it warrants holding this feature.