As extensões têm acesso a privilégios especiais no navegador, o que as torna um alvo atraente para invasores. Se uma extensão for comprometida, todos os usuários dela vão ficar vulneráveis a intrusões maliciosas e indesejadas. Para manter uma extensão segura e proteger os usuários, incorpore estas práticas.
Proteger contas de desenvolvedor
O código da extensão é enviado e atualizado pelas Contas do Google. Se as contas dos desenvolvedores forem comprometidas, um invasor poderá enviar código malicioso diretamente para todos os usuários. Proteja essas contas ativando a autenticação de dois fatores , de preferência com uma chave de segurança.
Usar funções de membro adequadas
Se o editor tiver vários membros, verifique se a função concedida a cada usuário é adequada.
Nunca usar HTTP
Ao solicitar ou enviar dados, evite uma conexão HTTP. Presuma que qualquer conexão HTTP terá espiões ou conterá modificações. O HTTPS sempre deve ser preferido, já que tem segurança integrada que evita 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 as APIs e os sites de que dependem.
Limitar os privilégios de uma extensão limita o que um possível invasor pode explorar.
Fetch() entre origens
Uma extensão só pode usar fetch() e XMLHttpRequest() para receber recursos da
extensão e dos domínios especificados nas permissões. Observe que as chamadas para ambos são interceptadas pelo gerenciador fetch no service worker.
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"host_permissions": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"manifest_version": 3
}
A extensão no exemplo acima solicita acesso a qualquer coisa em developer.chrome.com e subdomínios do Google listando "https://developer.chrome.com/*" e "https://*.google.com/*" nas permissões. Se a extensão fosse comprometida, ela ainda teria permissão para interagir apenas com sites que atendessem ao padrão de correspondência. O invasor teria apenas capacidade limitada de acessar "https://user_bank_info.com" ou
interagir com "https://malicious_website.com".
Limitar campos de manifesto
Incluir chaves e permissões desnecessárias no manifesto cria vulnerabilidades e torna uma extensão mais visível. Limite os campos do manifesto àqueles de que a extensão depende.
Pode ser conectado externamente
Use o campo "externally_connectable" para declarar com quais extensões externas e páginas da Web a
extensão vai trocar informações. Restringir com quem a extensão pode se conectar externamente a
fontes confiáveis.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"accepts_tls_channel_id": false
},
...
}
Recursos acessíveis pela Web
Tornar os recursos acessíveis pela Web, em "web_accessible_resources", faz com que uma extensão seja detectável por sites e invasores.
{
...
"web_accessible_resources": [
{
"resources": [ "test1.png", "test2.png" ],
"matches": [ "https://web-accessible-resources-1.glitch.me/*" ]
}
]
...
}
Quanto mais recursos acessíveis à Web estiverem disponíveis, mais caminhos um possível invasor poderá explorar. Mantenha esses arquivos no mínimo possível.
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 e evite ataques de script entre sites. Se a extensão carregar recursos apenas dela mesma, registre o seguinte:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "default-src 'self'"
},
"manifest_version": 3
}
Se a extensão precisar usar o WebAssembly ou aumentar as restrições em páginas em sandbox, ela poderá ser adicionada:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';",
"sandboxed_pages":"script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
},
"manifest_version": 3
}
Evite document.write() e innerHTML
Embora seja mais simples criar elementos HTML dinamicamente com document.write() e innerHTML,
isso deixa a extensão e as páginas da Web de que ela depende abertas para que invasores insiram
scripts maliciosos. Em vez disso, crie manualmente nós DOM e use innerText para inserir conteúdo dinâmico.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
Usar scripts de conteúdo com cuidado
Embora os scripts de conteúdo vivam em um mundo isolado, eles não estã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 surpreendentes do padrão da Web, 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 renderização da página da Web. Isso torna os scripts de conteúdo vulneráveis ao vazamento de dados por ataques de canal lateral (por exemplo, Spectre) e a serem acessados indevidamente por um invasor se uma página da Web mal-intencionada comprometer o processo de renderização.
Operações que usam dados sensíveis (como informações particulares de um usuário) ou APIs do Chrome com acesso às funções do navegador precisam ser realizadas no service worker das extensões. Evite expor acidentalmente privilégios de extensão a scripts de conteúdo:
- Suponha que 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 script em vários locais.
- Considere que todos os dados enviados ao script de conteúdo podem vazar para a página da Web. Não envie dados sensíveis (por exemplo, secrets da extensão, dados de outras origens da Web, histórico de navegação) para scripts de conteúdo.
- Limitar o escopo de ações privilegiadas que podem ser acionadas por scripts de conteúdo. Não permita que 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 os métodos
fetch()ouchrome.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 recebidos e higienizando todas as entradas.
Uma extensão só deve se registrar para runtime.onMessageExternal se esperar
comunicação de um site ou extensão externa. Sempre valide 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 pelo evento runtime.onMessage da própria extensão precisam ser analisadas para garantir que o 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.");
});