Proteja-se

As extensões têm acesso a privilégios especiais no navegador, o que as torna um alvo atraente para ataques. Se uma extensão for comprometida, todos os usuários dela ficarão vulneráveis a intrusões maliciosas e indesejadas. Incorporando essas práticas para manter uma extensão segura e seus usuários protegidos.

Proteger contas de desenvolvedor

O código da extensão é enviado e atualizado usando as Contas do Google. Se as contas dos desenvolvedores forem comprometidas, um invasor poderá enviar um código malicioso diretamente para todos os usuários. Para proteger essas contas, crie contas de desenvolvedor específicas e ative a autenticação de dois fatores, de preferência com uma chave de segurança .

Manter grupos seletivos

Ao usar a publicação em grupo, mantenha o grupo confinado a desenvolvedores confiáveis. Não aceite solicitações de associação de pessoas desconhecidas.

Nunca use HTTP

Ao solicitar ou enviar dados, evite uma conexão HTTP. Suponha que todas as conexões HTTP tenham invasões ou conter modificações. O HTTPS é sempre recomendado, já que ele tem segurança integrada que burla a maioria dos ataques "man-in-the-middle".

Solicitar permissões mínimas

O navegador Chrome limita o acesso de uma extensão aos privilégios que foram explicitamente solicitados no manifesto. As extensões precisam minimizar as permissões registrando apenas APIs e sites de que elas dependem. O código arbitrário deve ser mínimo.

A limitação dos privilégios de uma extensão limita o que um possível invasor pode explorar.

XMLHttpRequest de origem cruzada

Uma extensão só pode usar XMLHttpRequest para receber recursos dela mesma e de domínios especificados nas permissões.

{
  "name": "Very Secure Extension",
  "version": "1.0",
  "description": "Example of a Secure Extension",
  "permissions": [
    "/*",
    "https://*.google.com/"
  ],
  "manifest_version": 2
}

Esta extensão solicita acesso a qualquer item em developer.chrome.com e subdomínios do Google listando "/*" e "https://*google.com/" nas permissões. Se a extensão for comprometida, ela ainda vai ter permissão apenas para interagir com sites que atendam ao padrão de correspondência. O invasor não poderá acessar "https://user_bank_info.com" ou interagir com "https://malicious_website.com".

Limitar campos do manifesto

A inclusão de registros desnecessários no manifesto cria vulnerabilidades e torna uma extensão mais visível. Limite os campos do manifesto àqueles de que a extensão depende e forneça registros de campo específicos.

Conectável externamente

Use o campo externally_connectable para declarar com quais extensões e páginas da Web externas a extensão trocará informações. Restrinja com quem a extensão pode se conectar externamente a fontes confiáveis.

{
  "name": "Super Safe Extension",
  "externally_connectable": {
    "ids": [
      "iamafriendlyextensionhereisdatas"
    ],
    "matches": [
      "/*",
      "https://*google.com/"
    ],
    "accepts_tls_channel_id": false
  },
  ...
}

Recursos acessíveis pela Web

Ao tornar os recursos acessíveis pela Web, em web_accessible_resources, uma extensão será detectada por sites e invasores.

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

Quanto mais recursos acessíveis pela Web estiverem disponíveis, mais caminhos um possível invasor pode explorar. Use o mínimo possível de arquivos.

Incluir uma Política de Segurança de Conteúdo explícita

Inclua uma política de Segurança de Conteúdo para a extensão no manifesto para evitar ataques de scripting em vários sites. Se a extensão só carregar recursos dela mesma, registre o seguinte:

{
  "name": "Very Secure Extension",
  "version": "1.0",
  "description": "Example of a Secure Extension",
  "content_security_policy": "default-src 'self'"
  "manifest_version": 2
}

Se a extensão precisar incluir scripts de hosts específicos, eles poderão ser incluídos:

{
  "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
}

Evitar APIs executáveis

As APIs que executam código precisam ser substituídas por alternativas mais seguras.

document.write() e innerHTML

Embora possa ser mais simples criar elementos HTML dinamicamente com document.write() e innerHTML, ele deixa a extensão e as páginas da Web de que ela depende, abertas a invasores que inserem scripts maliciosos. Em vez disso, crie nós DOM manualmente e use innerText para inserir conteúdo dinâmico.

function constructDOM() {
  let newTitle = document.createElement('h1');
  newTitle.innerText = host;
  document.appendChild(newTitle);
}

eval()

Evite usar eval() sempre que possível para evitar ataques, porque eval() vai executar qualquer código transmitido a ele, o que pode ser malicioso.

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();

Em vez disso, prefira métodos mais seguros e rápidos, como 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();

Use scripts de conteúdo com cuidado

Embora os scripts de conteúdo vivam em um mundo isolado, eles não são imunes a ataques:

  • Os scripts de conteúdo são a única parte de uma extensão que interage diretamente com a página da Web. Por isso, páginas da Web hostis podem manipular partes do DOM de que o script de conteúdo depende ou explorar comportamentos padrão da Web surpreendentes, como itens nomeados.
  • Para interagir com o DOM de páginas da Web, os scripts de conteúdo precisam ser executados no mesmo processo de renderizador que a página da Web. Isso deixa os scripts de conteúdo vulneráveis a vazamentos de dados com ataques de canal lateral (por exemplo, Spectre) e de ser invadido por um invasor se uma página da Web maliciosa comprometer o processo do renderizador.

O trabalho confidencial precisa ser executado em um processo dedicado, como o script em segundo plano da extensão. Evite expor acidentalmente privilégios de extensão a scripts de conteúdo:

  • Suponha que as mensagens de um script de conteúdo possam ter sido criadas por um invasor (por exemplo, valide e limpe todas as entradas e proteja seus scripts contra scripts entre sites).
  • Suponha que os dados enviados ao script de conteúdo possam vazar para a página da Web. Não envie dados confidenciais (por exemplo, segredos da extensão, dados de outras origens da Web, histórico de navegação) para scripts de conteúdo.
  • Limitar o escopo das ações privilegiadas que podem ser acionadas por scripts de conteúdo. Não permita que os scripts de conteúdo acionem solicitações para URLs arbitrários ou transmitam argumentos arbitrários para APIs de extensão (por exemplo, não permita a transmissão de URLs arbitrários para a API fetch ou chrome.tabs.create).

Registrar e limpar entradas

Proteja uma extensão contra scripts maliciosos limitando os listeners apenas ao que a extensão espera, validando os remetentes dos dados de entrada e limpando todas as entradas.

Uma extensão só precisará ser registrada em runtime.onRequestExternal se estiver esperando comunicação de um site ou extensão externo. Sempre confirme se o remetente corresponde a uma fonte confiável.

// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.id === kFriendlyExtensionId)
      doSomething();
});

Até mesmo as mensagens por meio do evento runtime.onMessage da própria extensão precisam ser examinadas para garantir que MessageSender não seja de um script de conteúdo comprometido.

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.allowedAction)
    console.log("This is an allowed action.");
});

Impeça que uma extensão execute o script de um invasor limpando as entradas do usuário e os dados recebidos, mesmo da própria extensão e de fontes aprovadas. Evite APIs executáveis.

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