Un scanner complet de malware pour extensions de navigateur (.xpi) qui vérifie de nombreuses astuces de malware courantes telles que : les tactiques d'obfuscation des voleurs d'identifiants, la stéganographie, les payloads base64, les astuces zip, l'exécution de code à distance, les astuces polyglottes et les astuces de métadonnées, dans le but de fournir à l'analyste des informations sur les zones où une analyse plus approfondie est nécessaire.
Un outil en ligne de commande qui analyse les fichiers d'extension Firefox (.xpi) à la recherche de signes de malware, d'obfuscation, de charges utiles cachées, de stéganographie et d'autres techniques utilisées pour faire passer du code malveillant devant les équipes de révision des extensions.
extension-scanner.py ouvre une extension Firefox et effectue une batterie de vérifications de sécurité sur chaque fichier qu'elle contient. Il produit ensuite un rapport coloré avec des résultats classés par sévérité.
| Catégorie | Ce qu'il recherche |
|---|---|
| Permissions | Permissions dangereuses ou trop larges (nativeMessaging, <all_urls>, debugger, desktopCapture, etc.) |
| Politique de sécurité du contenu | unsafe-inline, unsafe-eval, sources de scripts distantes dans la CSP |
| Obfuscation JavaScript | eval(), atob(), abus du constructeur Function(), séquences d'échappement hexadécimales, réassemblage par split/join/reverse, littéraux de chaînes encodés, setTimeout avec des arguments chaîne |
| URL suspectes | Domaines externes codés en dur classés comme connus-mauvais (liste noire → ÉLEVÉ), inconnus (pas sur la liste blanche → MOYEN), ou connus-bons (liste blanche → supprimé). Exécutez --update-blocklist pour actualiser la liste noire des domaines à partir de URLhaus et de la liste de Peter Lowe. |
| Identifiants et secrets | Clés API, jetons (AWS, GitHub, Slack, Google), mots de passe, clés privées et adresses IP codés en dur |
| Charges utiles Base64 | Décode les blocs base64 intégrés et les scanne à la recherche d'exécutables, de scripts et de code réseau |
| Stéganographie PNG | Détecte les données ajoutées après PNG IEND et décode automatiquement le trailer (base64, zlib, gzip et combinaisons) ; les charges utiles décodées sont scannées récursivement pour l'obfuscation JS, les identifiants et les URLs suspectes. Détecte également les types de chunks inconnus, les anomalies de canal LSB et une entropie de pixel inhabituellement élevée |
| Métadonnées de fichier | Détection par octet magique des exécutables (.exe, .elf, .dylib), extensions doubles (ex. photo.png.js), noms de fichiers suspects (keylog, miner, wallet) |
| Fichiers polyglottes | Fichiers valides simultanément dans deux formats (ex. HTML + ZIP) |
CRITICAL — Presque certainement malveillant ; enquête immédiate requiseHIGH — Fortement suspect ; justifie un examen attentifMEDIUM — Potentiellement risqué ; à examiner dans son contexteLOW — Préoccupation mineure ; informatifINFO — Métadonnées (hash, taille du fichier, etc.)python3.11, python3.12 ou python3.13**python3-venv** - Requis si vous utilisez des environnements virtuelsUtilisation d'environnements virtuels :
sudo apt install python3 python3-venv
git clone https://github.com/ernos/extension-scanner.git
cd extension-scanner
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
**python3-numpy** - Recommandé pour la stéganographie, installation système (sinon pip install -r requirements.txt)pip install pillow numpy
#System-wide install on ubuntu:
sudo apt install python3-pillow python3-numpy
git clone https://github.com/ernos/extension-scanner.git
cd extension-scanner
chmod +x extension-scanner.py
mkdir -p ~/.local/share/bin
ln -s $PWD/extension-scanner.py ~/.local/share/bin/extension-scanner
# Required for LSB steganography analysis (optional but recommended)
pip install pillow numpy
# OPTION 1. Only for current user:
# Enable bash completions for simpler use (TAB for autocompleting commands)
mkdir -p ~/.local/share/bash-completion/completions
cp extension-scanner-completions ~/.local/share/bash-completion/completions
echo "source ~/.local/share/bash-completion/completions/extension-scanner-completions" >> ~/.bashrc
# OPTION 2. Enable completions globally for all users (Should be auto-sourced from your .bashrc)
cp extension-scanner-completions /usr/share/bash-completion/completions
Si Pillow/NumPy ne sont pas installés, l'outil fonctionne quand même — les vérifications LSB et d'entropie des pixels sont simplement ignorées, et un avertissement est affiché.
usage: xpiscanner [-h] [--update-blocklist] [--min-severity {CRITICAL,HIGH,MEDIUM,LOW,INFO}] [--json] [--compact] [-v] [-m] [--scans CHECK [CHECK ...]]
[targets ...]
Firefox Extension Scanner - Scans XPI files for security risks and malware indicators
positional arguments:
targets One or more XPI files or directories containing XPIs to analyze
options:
-h, --help show this help message and exit
--update-blocklist, --update, -u
Fetch fresh domain blocklists from URLhaus and Peter Lowe's list, merge with the bundled snapshot, and saves to
/home/peb/projects/Firefox-Extensions/extension-scanner/blocklist.json. Exits after updating.
--min-severity {CRITICAL,HIGH,MEDIUM,LOW,INFO}
Minimum severity to display (CRITICAL, HIGH, MEDIUM, LOW, INFO; default: INFO)
--json Output results as JSON instead of formatted text
--compact, -c Print each finding on 1-2 lines instead of the default 3-line format
-v, --verbose Enable verbose output: show additional context for findings
-m, --manifest Show full extension manifest for each target
--scans, -s CHECK [CHECK ...]
Limit analysis to specific check types. Choices: anti-analysis, api-abuse, credentials, cross-file,
file-meta, hidden-elements, obfuscation, payloads, permissions, polyglot, remote-code,
signatures, steganography, time-bomb, zip-tricks. Omit to run all checks (default).
extension-scanner.py — Analyze Firefox (and other browsers) extension XPI files for security risks and malware indicators.
Read README.md for information on how to interpret findings, limitations, and best practices for use.
This tool is intended for security researchers, analysts, and advanced users who want to perform a
comprehensive static analysis of browser extensions. It should work well for other browsers as well,
but this has only been tested on firefox.
Usage:
python3 extension-scanner.py [OPTIONS] targets...
Targets can be individual .xpi files or directories containing .xpi files. Use glob patterns (e.g. *.xpi) for convenience.
Available check types:
permissions Dangerous/broad manifest permissions and CSP issues
remote-code Background pages or service workers loaded from remote URLs
obfuscation eval/atob/encoding tricks, suspicious URLs, high-entropy strings
payloads Base64-encoded blobs decoded and scanned for executables/scripts
steganography PNG appended data (auto-decoded via base64/zlib/gzip), unknown chunks, LSB channel analysis
credentials Hardcoded API keys, tokens, passwords, private keys, IP addresses
file-meta Magic bytes, double extensions, suspicious filenames, file entropy
polyglot Files valid in two formats simultaneously (e.g. HTML+ZIP)
zip-tricks Path traversal, null bytes, duplicate entries, ZIP comments
cross-file HTML class tokens cross-referenced against JS localStorage keys
signatures Known strings from confirmed malicious extension families (qingcaila, YTMP4, etc.)
api-abuse Browser API calls indicating data theft or exfiltration (cookies, tabs, history, keylogger, clipboard, executeScript)
hidden-elements Invisible iframes, zero-dimension element injection, tracking pixels (new Image().src)
time-bomb Long-delay setTimeout, Date.now() gates, localStorage install-date checks, Math.random() gates
anti-analysis navigator.webdriver, zero-size window, bare debugger statement, performance.now() timing
Examples:
python3 extension-scanner.py extension.xpi
python3 extension-scanner.py *.xpi
python3 extension-scanner.py /path/to/extensions/
python3 extension-scanner.py a.xpi b.xpi --min-severity HIGH
python3 extension-scanner.py ext.xpi --scans obfuscation payloads
python3 extension-scanner.py ext.xpi --s steganography zip-tricks file-meta
python3 extension-scanner.py ext.xpi --verbose
python3 extension-scanner.py --update-blocklist
python3 extension-scanner.py --manifest
Tips:
- Make sure to source scanner-completions.sh from your .bashrc or .zshrc to enable tab completion for --scans categories and target file paths.
- Use --min-severity to focus on the most critical findings first.
- Use --scans to limit the analysis to specific categories of checks if you're looking for something specific or want to speed up the scan.
- Review the full manifest with --manifest for context on permissions, content scripts, and other extension metadata that can help interpret findings.
- Regularly update the blocklist with --update-blocklist to ensure the latest malicious domains are included in the checks.
Credits:
Developed by Ernos @ https://www.yourdev.net
Email: max at yourdev.net
GitHub: https://www.github.com/ernos/extension-scanner
| Flag | Description |
|---|---|
--update-blocklist | Récupère les listes de domaines fraîches depuis URLhaus et la liste des serveurs de pub/malware de Peter Lowe, les fusionne avec l'instantané fourni, et les enregistre dans blocklist.json à côté du script. Se termine après la mise à jour. |
targets | Un ou plusieurs fichiers .xpi ou répertoires |
--min-severity | Filtrer la sortie : CRITICAL, HIGH, MEDIUM, LOW, INFO (par défaut : INFO) |
--json | Émet les résultats sous forme de document JSON au lieu du rapport lisible par un humain |
--verbose ou -v | Affiche le contenu de manifest.json et inclut environ 5 lignes de code autour de tout motif suspect trouvé |
--checks | Ne scanner que ces catégories de vérifications spécifiques (voir ci-dessous) |
| Catégories de vérifications disponibles | Description des vérifications dans la catégorie |
|---|---|
| permissions | Permissions de manifeste dangereuses/larges et problèmes de CSP |
| remote-code | Pages d'arrière-plan ou service workers chargés depuis des URLs distantes |
| obfuscation | Astuces eval/atob/encodage, URLs suspectes, chaînes à haute entropie |
| payloads | Blobs encodés en Base64 décodés et scannés pour des exécutables/scripts |
| steganography | Données ajoutées PNG, chunks inconnus, analyse de canal LSB |
| credentials | Clés API, jetons, mots de passe, clés privées, adresses IP codés en dur |
| file-meta | Octets magiques, extensions doubles, noms de fichiers suspects, entropie de fichier |
| polyglot | Fichiers valides simultanément dans deux formats (ex. HTML+ZIP) |
| zip-tricks | Traversée de chemin, octets nuls, entrées en double, commentaires ZIP |
| cross-file | Jetons de classe HTML croisés avec les clés localStorage JS |
| api-abuse | Appels d'API de navigateur indiquant un vol ou une exfiltration de données (cookies, onglets, historique, clavier, presse-papiers). CRITICAL lorsque la collecte + l'envoi réseau apparaissent dans le même fichier. |
| hidden-elements | Injection d'iframe invisible et pixels de suivi. HIGH lorsque l'iframe est masquée + ajoutée au DOM. |
| time-bomb | setTimeout à long délai, portes arithmétiques Date.now(), date d'installation localStorage, seuil Math.random(). |
| anti-analysis | navigator.webdriver, fenêtre de taille nulle, instruction debugger nue, arithmétique performance.now(). |
════════════════════════════════════════════════════════════════════════════
XPI ANALYZER — example.xpi
════════════════════════════════════════════════════════════════════════════
Overall verdict: HIGH RISK
Findings: 1 CRITICAL 3 HIGH 2 MEDIUM 1 LOW
── CRITICAL ────────────────────────────────────────────────────────────
[CRITICAL ] [JS_OBFUSCATION] content.js
eval() call — can execute arbitrary code from strings
Evidence: var x = eval(atob("dmFyIGE9MTs…"))
── HIGH ────────────────────────────────────────────────────────────────
[HIGH ] [PERMISSION] manifest.json
Dangerous permission: 'nativeMessaging' — Can spawn native OS …
Evidence: permissions: ['nativeMessaging', 'storage', '<all_urls>']
…
Lors de l'analyse de plusieurs fichiers, un tableau comparatif est imprimé après les rapports individuels montrant toutes les extensions côte à côte.
| Code | Signification |
|---|---|
0 | Aucun résultat CRITICAL ou HIGH |
1 | Au moins un résultat HIGH |
2 | Au moins un résultat CRITICAL |
Ceci permet une utilisation simple dans des pipelines CI ou des scripts shell :
python3 extension-scanner.py extension.xpi --min-severity HIGH
if [ $? -eq 2 ]; then echo "CRITICAL issues found!"; fi
HIGH.Maximilian Cornett
GNU General Public License - Cet outil est destiné uniquement à la recherche en sécurité et à l'analyse défensive.
| Astuces ZIP |
| Entrées de traversée de chemin, octets nuls dans les noms de fichiers, entrées en double pouvant tromper les analyseurs, commentaires ZIP porteurs de charge utile |
| Code distant | Pages d'arrière-plan ou service workers chargés depuis des URLs distantes |
| Haute entropie | Fichiers ou littéraux de chaînes avec une entropie suspecte (probablement des charges utiles cryptées ou compressées) |
| Abus d'API | Appels d'API d'extension de navigateur indiquant un vol ou une exfiltration de données : cookies.getAll({}), tabs.query({}), history.search, écouteurs de clavier, lectures de presse-papiers, scripting.executeScript avec une fonction dynamique. Passe à CRITIQUE lorsqu'un appel de collecte de données est associé à un envoi réseau sortant dans le même fichier. |
| Éléments cachés | Iframes invisibles créées dynamiquement (display:none, dimensions nulles) injectées dans le DOM — pings d'affiliation silencieux ou canaux C2. Pixels de suivi via new Image().src pointant vers des URLs externes. |
| Bombe à retardement | setTimeout/setInterval avec des délais ≥ 5 minutes ; portes arithmétiques Date.now() ; vérifications de la date d'installation dans localStorage qui activent un comportement des jours après la première exécution ; portes de seuil Math.random() qui ne se déclenchent que sur une fraction des chargements de page. |
| Anti-analyse | Vérifications navigator.webdriver ; comparaisons de fenêtres de largeur/hauteur nulle ; instructions debugger nues ; arithmétique performance.now() utilisée pour la détection de sandbox basée sur le timing. |