# Browser Extension Development
Everything around the development of the browser extension. The browser extensions are nothing but some special packaged web clients, with some additional sugar for panels and so on.
# Preamble
This whole guide is based on Ubuntu 22.04 LTS. Other Ubuntu and Debian based systems should be similar if not even identical.
We assume that you already have somewhere a Psono client development environment up. If not follow the guide to develop clients.
# Development
There are a lot of different ways to develop browser extensions. The most simple one is to create the unpackaged files and then load them in the browser:
# Chrome
Build
To build the browser extension execute the following command:
npm run buildchrome
Follow this guide and load the extension from
psono-client/build/chrome
:In short:
- open Chrome
- enter "chrome://extensions" in the URL bar
- Ensure that the Developer mode checkbox in the top right-hand corner is checked.
- click "Load unpacked extension…"
- Navigate to
psono-client/build/chrome
, and select it.
# Firefox
Build
To build the browser extension execute the following command:
npm run buildfirefox
Follow this guide and load the extension from
psono-client/build/firefox
:In short:
- open Firefox
- enter "about:debugging" in the URL bar
- click "Load Temporary Add-on"
- open
psono-client/build/firefox
and select any file inside.
# Release
# Chrome
The instruction will describe how to build / package and deploy the Chrome browser extension
Build
To build the browser extension execute the following command:
npm run buildchrome
Packaging
First, we go into the build folder for the Chrome extension:
cd psono-client/build/chrome/
And zip everything:
zip -r ../../chrome-extension.zip *
And and lets go back up to the root of the project where our
chrome-extension.zip
is now located:cd ../..
Deployment
To deploy everything now to the Chrome Web Store execute the following:
npm run deploychrome
This will look for a
dist/chrome/psono.chrome.PW.zip
and deploy it. Replace the following variables:$webstore_client_id # e.g.: 12345678-XXXXXXXXX...XXXX.apps.googleusercontent.com $webstore_client_secret # e.g.: ABCDEFg-AaaaAAaaAKaasd9 $webstore_refresh_token # X/XXXXXxxxxXXXXX_XXxxxXxXXXxxx $webstore_app_id # e.g.: eljmjmgjkbmpmfljlmklcfineebidmlo
More infos can be found here:
https://www.npmjs.com/package/webstore-upload (opens new window)
https://developer.chrome.com/webstore/using_webstore_api (opens new window)
# Firefox
The instruction will describe how to build / package and deploy the Firefox browser extension
Build
To build the browser extension execute the following command:
npm run buildfirefox
Packaging
First, we go into the build folder for the Firefox extension:
cd psono-client/build/firefox/
And zip everything:
zip -r ../../firefox-extension.zip *
And and lets go back up to the root of the project where our
firefox-extension.zip
is now located:cd ../..
Deployment
To deploy everything now to Firefox Add-ons execute the following:
npm run deployfirefox
This will look for a
firefox-extension.zip
and deploy it. Replace the following variables:$mozilla_jwt_issuer # e.g.: user:12345689:123 $mozilla_jwt_secret # e.g.: asdasdasd45654334456asdasdasd6345645456asdasdsad456456456 $mozilla_addon_id # e.g.: {4cea82d7-5815-47eb-a7fe-2a5fd4974126} $mozilla_version # e.g.: 1.2.3
More infos can be found here:
# Development Best Practices
# Extension Security & Architecture
- Manifest Security: Extensions use Manifest V3 (Chrome) and V2 (Firefox) - review permission changes carefully
- Content Script Isolation: Scripts run in different security contexts with varying DOM access
- Background Script Security: Service workers have no DOM access but can access extension APIs
- Cross-Origin Requests: Extensions bypass CORS but must declare host permissions
# Security-Critical Areas
- Content Scripts: Located in
src/*/data/js/content-script.js
- injected into web pages, handle form detection - Background Scripts:
src/chrome/data/js/service-worker-load.js
andsrc/firefox/data/js/service-worker-load.js
- Manifest Permissions: Review any permission changes in
src/chrome/manifest.json
andsrc/firefox/manifest.json
- Message Passing: Secure communication between content scripts, popup, and background scripts
# Testing Browser Extensions
# Build and test Chrome extension
npm run buildchrome
# Load unpacked extension from build/chrome/ directory
# Build and test Firefox extension
npm run buildfirefox
# Load temporary addon from build/firefox/ directory
# Run unit tests (covers shared web client logic)
npm test
# Extension-Specific Development Guidelines
- Permission Principle: Request minimal permissions - add new permissions only when absolutely necessary
- Content Security Policy: Extensions must comply with strict CSP - avoid inline scripts and eval()
- Web Accessible Resources: Limit exposed resources to prevent malicious access
- Storage Security: Use chrome.storage.local for sensitive data, never localStorage in content scripts
- Cross-Browser Compatibility: Test functionality across Chrome and Firefox implementations
# Code Review Focus Areas
- Manifest Changes: Any permission additions require security review and justification
- Content Script Injection: Verify secure DOM manipulation and event handling
- Message Validation: All messages between scripts must be validated and sanitized
- Host Permission Usage: Ensure host permissions are used only for intended functionality
- API Usage: Verify proper usage of browser extension APIs and error handling
# Debugging & Development Tools
# Chrome Extension Debugging
# 1. Open chrome://extensions
# 2. Enable Developer mode
# 3. Load unpacked extension
# 4. Use "Inspect" on background page and popup
# Firefox Extension Debugging
# 1. Open about:debugging
# 2. Enable Add-on Debugging
# 3. Load temporary addon
# 4. Use "Debug" for background scripts
# Common Security Pitfalls
- Content Script Vulnerabilities: Avoid modifying untrusted DOM content without sanitization
- Message Injection: Always validate origin and content of messages between scripts
- Permission Creep: Regular audits of requested permissions vs. actual usage
- Data Leakage: Ensure sensitive data doesn't leak to web page contexts