Bénéficiez d'une sécurité optimale

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, chaque utilisateur de cette extension devient vulnérable aux intrusions malveillantes et indésirables. Ces pratiques permettent d'assurer la sécurité d'une extension et la protection de ses utilisateurs.

Protéger les comptes de développeur

Le code de l'extension est importé et mis à jour via les comptes Google. Si les comptes d'un développeur sont piratés, un pirate informatique peut transmettre du code malveillant directement à tous les utilisateurs. Pour les protéger, créez des comptes de développeur spécifiques et activez l'authentification à deux facteurs, de préférence avec une clé de sécurité .

Gardez les groupes sélectifs

Si vous utilisez la publication groupée, limitez le groupe aux développeurs de confiance. N'acceptez pas les demandes d'appartenance de personnes inconnues.

Ne jamais utiliser le protocole HTTP

Lorsque vous demandez ou envoyez des données, évitez d'utiliser une connexion HTTP. Supposons que les connexions HTTP soient espionnées ou contiennent des modifications. Le protocole HTTPS doit toujours être privilégié, car sa sécurité intégrée 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 droits qui ont été explicitement demandés dans le fichier manifeste. Les extensions doivent réduire leurs autorisations en n'enregistrant que les API et les sites Web dont elles dépendent. Le code arbitraire doit être le plus limité possible.

Limiter les privilèges d’une extension limite ce qu’un attaquant potentiel peut exploiter.

XMLHttpRequest multi-origine

Une extension ne peut utiliser XMLHttpRequest que pour obtenir les ressources 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 du site developer.chrome.com et des sous-domaines de Google en indiquant "/*" et "https://*google.com/" dans les autorisations. Si l'extension était compromise, elle ne serait autorisée à interagir qu'avec les sites Web répondant 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 sur lesquels l'extension s'appuie et accordez un enregistrement de champ spécifique.

Connexion 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 utilisateurs avec lesquels l'extension peut se connecter en externe aux 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

Si vous rendez des ressources accessibles sur le Web, conformément à la web_accessible_resources, une extension sera détectable par les sites Web et les pirates informatiques.

{
  ...
  "web_accessible_resources": [
    "images/*.png",
    "style/secure_extension.css",
    "script/secure_extension.js"
  ],
  ...
}

Plus les ressources disponibles sur le Web sont nombreuses, plus un potentiel pirate informatique peut exploiter de multiples possibilités. Limitez ces fichiers au maximum.

Inclure une stratégie de sécurité du contenu explicite

Incluez une stratégie de sécurité du contenu pour l'extension dans le fichier manifeste afin d'empêcher les attaques par script intersites. Si l'extension ne charge que les ressources 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, vous pouvez les inclure:

{
  "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 puisse être plus simple de créer dynamiquement des éléments HTML avec document.write() et innerHTML, il laisse l'extension et les pages Web dont dépend l'extension, ouvertes aux pirates informatiques insérant des scripts malveillants. À la place, créez 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 empêcher 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();

Privilégiez plutôt des méthodes plus sûres et plus rapides comme 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

Même si 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. C'est pourquoi des pages Web hostiles peuvent manipuler des parties du DOM dont dépend le script de contenu ou exploiter un comportement inattendu standard du 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 moteur de rendu que la page Web. Les scripts de contenu sont ainsi vulnérables aux fuites de données via des attaques par canal secondaire (par exemple, Spectre) et d'être pris par un pirate informatique si une page Web malveillante compromet le processus du moteur 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 des droits d'extension aux scripts de contenu:

  • Supposons que des messages provenant d'un script de contenu aient été créés par un pirate informatique (par exemple, validez et désinfectez toutes les entrées et protégez vos scripts contre les scripts intersites).
  • Supposons que les données envoyées au script de contenu puissent être transmises à la page Web. N'envoyez pas de données sensibles (telles que des secrets de l'extension, des données d'autres origines Web et l'historique de navigation) aux scripts de contenu.
  • Limitez la portée des actions privilégiées pouvant ê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 fetch ou chrome.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 pour runtime.onRequestExternal que si elle attend des communications 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 via l'événement runtime.onMessage à partir de l'extension elle-même doivent être examinés pour s'assurer que 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 à partir de l'extension elle-même et des sources approuvées. Évitez les API exécutables.

function sanitizeInput(input) {
    return input.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
}