Les extensions ont accès à des privilèges spéciaux dans le navigateur, ce qui en fait une cible attrayante pour les pirates informatiques. Si une extension est compromise, tous ses utilisateurs deviennent vulnérables aux intrusions malveillantes et indésirables. Pour sécuriser une extension et protéger ses utilisateurs, adoptez les pratiques suivantes.
Protéger les comptes de développeur
Le code d'extension est importé et mis à jour via des comptes Google. Si les comptes des développeurs sont compromis, un pirate informatique peut envoyer du code malveillant directement à tous les utilisateurs. Protégez ces comptes en créant des comptes de développeur spécifiques et en activant l'authentification à deux facteurs , de préférence avec une clé de sécurité .
Limiter les groupes
Si vous utilisez l'éditeur de groupe, limitez le groupe aux développeurs de confiance. N'acceptez pas les demandes d'adhésion de personnes inconnues.
Ne jamais utiliser HTTP
Lorsque vous demandez ou envoyez des données, évitez une connexion HTTP. Partez du principe que toutes les connexions HTTP seront écoutées ou modifiées. Il est toujours préférable d'utiliser HTTPS, car il dispose d'une sécurité intégrée qui contourne la plupart des attaques MITM ("man in the middle").
Demander des autorisations minimales
Le navigateur Chrome limite l'accès d'une extension aux privilèges qui ont été explicitement demandés dans le fichier manifeste. Les extensions doivent minimiser leurs autorisations en n'enregistrant que les API et les sites Web dont elles dépendent. Le code arbitraire doit être réduit au minimum.
Limiter les privilèges d'une extension limite ce qu'un pirate informatique potentiel peut exploiter.
XMLHttpRequest multi-origines
Une extension ne peut utiliser XMLHttpRequest que pour obtenir des ressources à partir d'elle-même et des domaines spécifiés dans les autorisations.
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"permissions": [
"/*",
"https://*.google.com/"
],
"manifest_version": 2
}
Cette extension demande l'accès à tous les éléments de developer.chrome.com et aux sous-domaines de Google en
listant "/*" et "https://*google.com/" dans les autorisations. Si l'
extension était compromise, elle n'aurait toujours l'autorisation d'interagir qu'avec les sites Web qui correspondent
au modèle de correspondance. Le pirate informatique ne pourrait pas accéder à "https://user_bank_info.com" ni
interagir avec "https://malicious_website.com".
Limiter les champs du fichier manifeste
L'inclusion d'enregistrements inutiles dans le fichier manifeste crée des failles et rend une extension plus visible. Limitez les champs du fichier manifeste à ceux dont l'extension dépend et fournissez un enregistrement de champ spécifique.
Connectable en externe
Utilisez le champ externally_connectable pour déclarer les extensions externes et les pages Web avec lesquelles l'
extension échangera des informations. Limitez les sources externes auxquelles l'extension peut se connecter à des sources de confiance.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"/*",
"https://*google.com/"
],
"accepts_tls_channel_id": false
},
...
}
Ressources accessibles sur le Web
Rendre les ressources accessibles sur le Web, sous les web_accessible_resources, rendra une
extension détectable par les sites Web et les pirates informatiques.
{
...
"web_accessible_resources": [
"images/*.png",
"style/secure_extension.css",
"script/secure_extension.js"
],
...
}
Plus il y a de ressources accessibles sur le Web, plus un pirate informatique potentiel peut exploiter de voies. Réduisez ces fichiers au minimum.
Inclure une règle de sécurité du contenu explicite
Incluez une règle de sécurité du contenu pour l'extension dans le fichier manifeste afin d'empêcher les attaques de script intersite. Si l'extension ne charge que des ressources à partir d'elle-même, enregistrez les éléments suivants :
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": "default-src 'self'"
"manifest_version": 2
}
Si l'extension doit inclure des scripts provenant d'hôtes spécifiques, ils peuvent être inclus :
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": "default-src 'self' https://extension.resource.com"
"manifest_version": 2
}
Éviter les API exécutables
Les API qui exécutent du code doivent être remplacées par des alternatives plus sûres.
document.write() et innerHTML
Bien qu'il soit plus simple de créer dynamiquement des éléments HTML avec document.write() et innerHTML, cela permet aux pirates informatiques d'insérer des scripts malveillants dans l'extension et les pages Web dont elle dépend. Créez plutôt manuellement des nœuds DOM et utilisez innerText pour insérer du contenu dynamique.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
eval()
Évitez d'utiliser eval() dans la mesure du possible pour prévenir les attaques, car eval() exécutera tout code qui lui est transmis, qui peut être malveillant.
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// WARNING! Might be evaluating an evil script!
var resp = eval("(" + xhr.responseText + ")");
...
}
}
xhr.send();
Préférez plutôt des méthodes plus sûres et plus rapides, telles que JSON.parse().
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// JSON.parse does not evaluate the attacker's scripts.
var resp = JSON.parse(xhr.responseText);
}
}
xhr.send();
Utiliser les scripts de contenu avec précaution
Bien que les scripts de contenu vivent dans un monde isolé, ils ne sont pas à l'abri des attaques :
- Les scripts de contenu sont la seule partie d'une extension qui interagit directement avec la page Web. Pour cette raison, les pages Web hostiles peuvent manipuler des parties du DOM dont dépend le script de contenu, ou exploiter un comportement surprenant des normes Web, comme les éléments nommés.
- Pour interagir avec le DOM des pages Web, les scripts de contenu doivent s'exécuter dans le même processus de rendu que la page Web. Cela rend les scripts de contenu vulnérables à la fuite de données via des attaques par canal auxiliaire (par exemple, Spectre) et à la prise de contrôle par un pirate informatique si une page Web malveillante compromet le processus de rendu.
Les tâches sensibles doivent être effectuées dans un processus dédié, tel que le script d'arrière-plan de l'extension. Évitez d'exposer accidentellement les privilèges d'extension aux scripts de contenu :
- Partez du principe que les messages d'un script de contenu ont peut-être été créés par un pirate informatique (par exemple, validez et nettoyez toutes les entrées, et protégez vos scripts contre les scripts intersites).
- Partez du principe que toutes les données envoyées au script de contenu peuvent être divulguées à la page Web. N'envoyez pas de données sensibles (par exemple, des secrets de l'extension, des données provenant d'autres origines Web, l'historique de navigation) aux scripts de contenu.
- Limitez la portée des actions privilégiées qui peuvent être déclenchées par les scripts de contenu. N'autorisez pas
les scripts de contenu à déclencher des requêtes vers des URL arbitraires ni à transmettre des arguments arbitraires aux
API d'extension (par exemple, n'autorisez pas la transmission d'URL arbitraires à l'API
fetchouchrome.tabs.create).
Enregistrer et nettoyer les entrées
Protégez une extension contre les scripts malveillants en limitant les écouteurs à ce que l'extension attend, en validant les expéditeurs des données entrantes et en nettoyant toutes les entrées.
Une extension ne doit s'enregistrer que pour runtime.onRequestExternal si elle attend
une communication d'un site Web ou d'une extension externe. Vérifiez toujours que l'expéditeur correspond à une source de confiance.
// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id === kFriendlyExtensionId)
doSomething();
});
Même les messages provenant de l'événement runtime.onMessage de l'extension elle-même doivent être examinés pour s'assurer que le MessageSender ne provient pas d'un script de contenu compromis.
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});
Empêchez une extension d'exécuter le script d'un pirate informatique en nettoyant les entrées utilisateur et les données entrantes, même celles provenant de l'extension elle-même et de sources approuvées. Évitez les API exécutables.
function sanitizeInput(input) {
return input.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
}