Skip to main content

Browser Autofill

Core Concepts

Content Scripts

A content script is a script that the browser inserts into the page source for each page that the browser loads. Content scripts can read and modify the contents of the page in which they are loaded, but they do not have access to the full set of browser APIs.

The Bitwarden extension uses content scripts in order to perform the Autofill functionality, as Autofill must both parse the page source to find the relevant fields and also alter the page source to fill in the fields with the relevant Cipher data.

The extension uses the following scripts for Autofill:

Content ScriptResponsibility
content/trigger-autofill-script-injection.tsFacilitates injection of the autofill feature through the extension background. Allows autofill-specific features to be conditionally presented based on user settings.
content/bootstrap-autofill.tsInitializes the core autofill feature script without the autofill overlay menu logic in place.
content/bootstrap-autofill-overlay.tsInitializes the core autofill feature script with the autofill overlay menu logic in place.
content/autofill-init.tsThe core autofill feature script, handles collection of form elements from the page through the CollectAutofillContentService class and filling of form fields through the InsertAutofillContentService class. Also conditionally handles presentation and behavior of the autofill overlay menu through the AutofillOverlayContentService class.
content/autofiller.tsTriggers autofill for users who have the "Enable Autofill on Page Load" setting enabled.
content/notificationBar.jsDetects when the user submits new or updated credentials on a website and triggers the Notification Bar UI.
note

There are other content scripts that Bitwarden uses, but these are the scripts related to the Autofill functionality.

Background Pages and Listeners

The Bitwarden browser extension uses background pages in order to listen and respond to actions triggered by the content scripts running on the browser tab. They do this by using BrowserApi.messageListener() to attach to chrome.runtime.onMessage.addListener().

The background scripts and listeners used in the Bitwarden extension are:

Background Page / ListenerResponsibility
runtime.background.tsHandles incoming requests related to core extension functionality.
notification.background.tsHandles incoming requests related to the notification bar.
overlay.background.tsHandles communication between the content scripts present on the current page and the overlay button and list pages that present the autofill overlay menu to the user.
commands.background.tsHandles incoming requests related to keyboard commands (including autofill) for Mv2 extensions.
onCommandListener.tsHandles incoming requests related to keyboard commands (including autofill) for Mv3 extensions.
contextMenu.background.tsHandles context menu actions (including autofill).
main.background.jsBootstraps the extension. It is relevant here only because it (arbitrarily) contains the collectPageDetailsForContentScript() method.

Messaging

We have established that the Bitwarden extension uses content scripts and background pages or listeners in order to perform Autofill. The last piece of the puzzle is the communication between them. The Autofill architecture leverages the extension messaging API in order to communicate between the extension UI, the background pages, and the content scripts that are running on each browser tab.

plantuml

Sending a request from the content script to the extension

To send a request from a content script to the extension, we have two services provided:

  • When Dependency Injection is available, the BrowserMessagingService should be used, with its provided send() method.
  • When no Dependency Injection is available, the static BrowserApi should be used, with its sendMessage() method.

On the extension background pages, we attach with BrowserApi.messageListener to receive the messages destined for the extension.

note

The BrowserMessagingService and BrowserApi abstract the chrome.runtime.sendMessage and chrome.runtime.onMessage.addListener exposed by the browser. If any direct references to this API are found, they should be refactored to use one of our abstractions.

Sending a request from the extension to the content script

We use BrowserApi.tabSendMessage to send messages from the extension to the content script running on the browser tab.

In the content script on the tab, we attach with chrome.runtime.onMessage.addListener to receive the messages destined for that tab.

note

The BrowserApi abstracts the chrome.tabs.sendMessage API. If any direct references to this API are found, they should be refactored to use our abstraction.