Developing Your First Chrome Extension

Presented by Philippe Arteau

Confoo 2023

About Me

  • Security Engineer at ServiceNow
  • Interested in application security, automation, cryptography, ...
  • Open-source developer
    • Find Security Bugs: Static Analysis for Java applications
    • Burp and ZAP Plugins: (Retire.js, CSP Auditor, Reissue Request Scripter, …)
Confoo 2023

Agenda

  1. Why developed a Chrome extension?
  2. Anatomy of a Chrome extension
    • manifest.json
    • Common components: popup, service worker, pages, context menu, ...
  3. Tooling
  4. Conclusion
Confoo 2023

Why develop a Chrome extension?

Confoo 2023

Why develop a Chrome extension?

Non-technical reasons

  • A great way to extended an existing web applications
    • Code repository, mail client, timesheet, etc.
  • The browser is the main software used by most "office jobs"
Confoo 2023

Why develop a Chrome extension?

Technical reasons

  • You can use your favorite Frontend framework (Vue, React, Angular, ...)
  • A great complement to an existing JS CLI
    • It can share code with other JS projects.
  • Lighter than yet another Electron application
Confoo 2023

Some extension ideas

  • Shortcuts for the QA team.
  • Tool to help complete timesheets with few clicks.
  • Searching feature specific to your code project.

Return on investment will differ if you have 1 user or 100+ users.

Confoo 2023

🎬 Demo

Acronym Finder

Code available at:
https://github.com/h3xstream/confoo-first-chrome-ext

Confoo 2023

Anatomy of Chrome extension

Confoo 2023

Manifest: Basic configuration

manifest.json

{
    "name": "Acronym Finder",
    "description": "Simple acronym extension",
    "version": "1.0",
    "manifest_version": 3,
    "permissions": ["storage", "activeTab", "scripting","contextMenus"],
    "host_permissions": [
      "*://*/*"
    ],
    //[...]
}
Confoo 2023

Components

  1. Service Worker (Also called Background scripts in MV2)
  2. Content Script
  3. Popup
  4. Context Menu
  5. Pages
Confoo 2023

1. Service worker

A event-based script that the browser runs in the background.
Chrome Developers Doc.

  • Place where multiple event handler can be register:
    • chrome.runtime.onInstalled.addListener
    • chrome.runtime.onMessage.addListener
    • chrome.contextMenus.onClicked.addListener
  • Isolated from other plugins.
  • Not directly connected to tabs and popup context.
Confoo 2023

1. Service worker: Isolated?

Components communicate with messages.

Confoo 2023

1. Service worker: Messages

Sending a message

const urlParameters = new URLSearchParams(queryParameters);

chrome.tabs.sendMessage(tabId, {
   type: "NEW",
   videoId: urlParameters.get("v"),
});
Confoo 2023

1. Service worker configuration

{
   //[...]
   "background": {
      "service_worker": "background.js"
   },
   //[...]
}
Confoo 2023

2. Content Script

Script loaded in the context of the tab.

  • It will have complete access to the DOM.
  • It needs to use message or storage API to communicate with the main service worker or the secondary pages.
Confoo 2023

3. Context menu

Context menu with option to extract the text selected.

Confoo 2023

3. Context menu: Initialisation

Confoo 2023

4. Popup

Confoo 2023

4. Popup (configuration)

manifest.json

{
    //[...]

    "action": {
      "default_popup": "popup.html",
      "default_icon": {...}
    },
    
    //[...]
}
Confoo 2023

4. Popup

popup.js implementation

As an alternative to Content Script, you can inject a script to a tab.

Confoo 2023

5. Pages

Confoo 2023

5. Pages

You can get the full URL to a resource using:

chrome.runtime.getURL("search.html")

Using a relative path from the popup will also work:

<a href="./settings.html">Settings</a>
Confoo 2023

Tooling

Confoo 2023

Webpack

[..] bundle JavaScript files for usage in a browser.

  • Allow you to use powerful JavaScript libraries from NPM
    • Parser, API, Data utilities, Your own modules
  • Allow you to use Bootstrap, SASS files, UI Framework
    • (Vue, React, ...)
Confoo 2023

Webpack fallback

module.exports = {
  //...
  resolve: {
    fallback: {
      assert: require.resolve('assert'),
      buffer: require.resolve('buffer'),
      console: require.resolve('console-browserify'),
      constants: require.resolve('constants-browserify'),
      crypto: require.resolve('crypto-browserify'),
      domain: require.resolve('domain-browser'),
      events: require.resolve('events'),
  //...

More info: Webpack configuration: resolve fallback

Confoo 2023

Testing

  • Don't forget to test your code !
  • The sample project include a demonstration of Jest integration.

Confoo 2023

Conclusion

Confoo 2023

Conclusion

Confoo 2023

There is more...

Confoo 2023

The End !

Social

Confoo 2023

Refer to the demonstration for each handler

Fallbacks are a way to reuse code built with builtin NodeJS dependencies

This is a test