# Metodologia de Pentesting em Extensões de Navegador
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras formas de apoiar o HackTricks: * Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos * **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Compartilhe suas técnicas de hacking enviando PRs para os repositórios github do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
## Informações Básicas Extensões de navegador são escritas em JavaScript e carregadas pelo navegador em segundo plano. Possuem seu próprio [DOM](https://www.w3schools.com/js/js_htmldom.asp), mas podem interagir com o DOM de outros sites. Isso significa que podem comprometer a confidencialidade, integridade e disponibilidade (CIA) de outros sites. ## Principais Componentes A estrutura de uma extensão é melhor visualizada e consiste em três componentes. Vamos analisar cada componente em detalhes.

http://webblaze.cs.berkeley.edu/papers/Extensions.pdf

### **Scripts de Conteúdo** Cada script de conteúdo tem acesso direto ao DOM de uma **página web única** e, portanto, está exposto a **entradas potencialmente maliciosas**. No entanto, o script de conteúdo não contém permissões além da capacidade de enviar mensagens para o núcleo da extensão. ### **Núcleo da Extensão** O núcleo da extensão contém a maioria dos privilégios/acessos da extensão, mas só pode interagir com o conteúdo da web por meio de [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) e scripts de conteúdo. Além disso, o núcleo da extensão não tem acesso direto à máquina hospedeira. ### **Binário Nativo** A extensão permite um binário nativo que pode **acessar a máquina hospedeira com todos os privilégios do usuário.** O binário nativo interage com o núcleo da extensão através da Interface de Programação de Aplicativos de Plug-in Netscape padrão ([NPAPI](https://en.wikipedia.org/wiki/NPAPI)) usada pelo Flash e outros plug-ins de navegador. ### Limites {% hint style="danger" %} Para obter os privilégios completos do usuário, um atacante deve convencer a extensão a passar entradas maliciosas do script de conteúdo para o núcleo da extensão e do núcleo da extensão para o binário nativo. {% endhint %} Cada componente da extensão é separado um do outro por **fortes barreiras de proteção**. Cada componente executa em um **processo separado do sistema operacional**. Scripts de conteúdo e núcleos de extensão executam em **processos sandbox** inacessíveis à maioria dos serviços do sistema operacional. Além disso, scripts de conteúdo são separados das páginas web associadas por **executarem em um heap JavaScript separado**. O script de conteúdo e a página web têm **acesso ao mesmo DOM subjacente**, mas os dois **nunca trocam ponteiros JavaScript**, prevenindo o vazamento de funcionalidades JavaScript. ## **`manifest.json`** Uma extensão do Chrome é apenas uma pasta ZIP com uma extensão de arquivo [.crx](https://www.lifewire.com/crx-file-2620391). O núcleo da extensão é o arquivo **`manifest.json`** na raiz da pasta, que especifica o layout, permissões e outras opções de configuração. Exemplo: ```json { "manifest_version": 2, "name": "My extension", "version": "1.0", "permissions": [ "storage" ], "content_scripts": [ { "js": [ "script.js" ], "matches": [ "https://example.com/*", "https://www.example.com/*" ], "exclude_matches": ["*://*/*business*"], } ], "background": { "scripts": [ "background.js" ] }, "options_ui": { "page": "options.html" } } ``` ### `content_scripts` Os scripts de conteúdo são **carregados** sempre que o usuário **navega para uma página correspondente**, no nosso caso qualquer página que corresponda à expressão **`https://example.com/*`** e que não corresponda à regex **`*://*/*/business*`**. Eles executam **como os próprios scripts da página** e têm acesso arbitrário ao [Document Object Model (DOM)](https://developer.mozilla.org/en-US/docs/Web/API/Document\_Object\_Model) da página. ```json "content_scripts": [ { "js": [ "script.js" ], "matches": [ "https://example.com/*", "https://www.example.com/*" ], "exclude_matches": ["*://*/*business*"], } ], ``` Para incluir ou excluir mais URLs, também é possível usar **`include_globs`** e **`exclude_globs`**. Este é um exemplo de script de conteúdo que adicionará um botão de explicação à página quando [a API de armazenamento](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage) recuperar o valor `message` do armazenamento da extensão. ```js chrome.storage.local.get("message", result => { let div = document.createElement("div"); div.innerHTML = result.message + " "; div.querySelector("button").addEventListener("click", () => { chrome.runtime.sendMessage("explain"); }); document.body.appendChild(div); }); ```
Quando este botão é clicado, o script de conteúdo **usa** a [**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage) **para enviar uma mensagem às páginas da extensão**. Isso ocorre porque um script de conteúdo só tem acesso direto a um punhado de APIs, como `storage`. Tudo o mais precisa ser feito pelas páginas da extensão, às quais os scripts de conteúdo podem enviar mensagens. {% hint style="warning" %} As **capacidades do script de conteúdo** diferem ligeiramente dependendo do navegador. Para navegadores baseados em Chromium, você pode encontrar a lista na [documentação dos Desenvolvedores Chrome](https://developer.chrome.com/docs/extensions/mv3/content\_scripts/#capabilities), para o Firefox, [MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content\_scripts#webextension\_apis) é a fonte definitiva.\ Lembre-se de que o Script de Conteúdo também pode **comunicar com os scripts de fundo** para que eles realizem ações e enviem de volta a resposta. {% endhint %} Para visualizar e depurar scripts de conteúdo no Chrome, você pode abrir o menu de ferramentas de desenvolvedor do Chrome em Opções > Mais ferramentas > Ferramentas do desenvolvedor OU (Pressione - Ctrl + Shift + I). Com as ferramentas de desenvolvedor exibidas, clique na **aba Fonte**, depois clique na aba **Scripts de Conteúdo**. Aqui você pode ver os scripts de conteúdo em execução das várias extensões e definir pontos de interrupção para monitorar o fluxo de execução.
### Scripts de conteúdo injetados {% hint style="success" %} Note que **Scripts de Conteúdo não são obrigatórios**, pois também é possível **injetar** scripts **dinamicamente** e **programaticamente** em páginas web via **`tabs.executeScript`**. Isso na verdade fornece controles mais **granulares**. {% endhint %} Para injetar um script de conteúdo programaticamente, sua extensão precisa de [permissões de host](https://developer.chrome.com/docs/extensions/reference/permissions) para a página na qual está tentando injetar scripts. As permissões de host podem ser concedidas **solicitando-as** como parte do manifesto da sua extensão ou temporariamente via [**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab)**.** #### Exemplo de extensão baseada em activeTab {% code title="manifest.json" %} ```json { "name": "My extension", ... "permissions": [ "activeTab", "scripting" ], "background": { "service_worker": "background.js" }, "action": { "default_title": "Action Button" } } ``` * **Injetar um arquivo JS ao clicar:** ```javascript // content-script.js document.body.style.backgroundColor = "orange"; //service-worker.js - Inject the JS file chrome.action.onClicked.addListener((tab) => { chrome.scripting.executeScript({ target: { tabId: tab.id }, files: ["content-script.js"] }); }); ``` * **Injetar uma função** ao clicar: ```javascript //service-worker.js - Inject a function function injectedFunction() { document.body.style.backgroundColor = "orange"; } chrome.action.onClicked.addListener((tab) => { chrome.scripting.executeScript({ target : {tabId : tab.id}, func : injectedFunction, }); }); ``` #### Exemplo com permissões de script ```javascript // service-workser.js chrome.scripting.registerContentScripts([{ id : "test", matches : [ "https://*.nytimes.com/*" ], excludeMatches : [ "*://*/*business*" ], js : [ "contentScript.js" ], }]); // ANother example chrome.tabs.executeScript(tabId, { file: "content_script.js" }); ``` Para incluir ou excluir mais URLs, também é possível usar **`include_globs`** e **`exclude_globs`**. ### Scripts de Conteúdo `run_at` O campo `run_at` controla **quando arquivos JavaScript são injetados na página web**. O valor preferido e padrão é `"document_idle"`. Os valores possíveis são: * **`document_idle`**: Sempre que possível * **`document_start`**: Após quaisquer arquivos de `css`, mas antes de qualquer outro DOM ser construído ou qualquer outro script ser executado. * **`document_end`**: Imediatamente após o DOM estar completo, mas antes de subrecursos como imagens e frames serem carregados. #### Via `manifest.json` ```json { "name": "My extension", ... "content_scripts": [ { "matches": ["https://*.nytimes.com/*"], "run_at": "document_idle", "js": ["contentScript.js"] } ], ... } ``` Via **`service-worker.js`** ```javascript chrome.scripting.registerContentScripts([{ id : "test", matches : [ "https://*.nytimes.com/*" ], runAt : "document_idle", js : [ "contentScript.js" ], }]); ``` ### `background` Quando scripts de conteúdo enviam uma mensagem, seu destino é a **página de background**. A página de background é uma página especial que está **sempre presente** a menos que especificado de outra forma no manifesto da extensão. Ela é invisível para o usuário, apesar de ser uma página regular com seu próprio DOM e tudo mais. Sua função é tipicamente coordenar todas as outras partes da extensão. {% hint style="success" %} Se uma página de background não for declarada explicitamente, o navegador irá gentilmente **gerar uma** automaticamente e garantir que todos os **scripts de background declarados sejam carregados** nela, como no exemplo anterior de manifest.json. {% endhint %} Exemplo de script de background: ```js chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request == "explain") { chrome.tabs.create({ url: "https://example.net/explanation" }); } }) ``` Ele utiliza a [API runtime.onMessage](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage) para ouvir mensagens. Quando uma mensagem `"explain"` é recebida, ele usa a [API tabs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) para abrir uma página em uma nova aba. Para depurar o script de background, você pode ir aos **detalhes da extensão e inspecionar o service worker,** isso abrirá as ferramentas de desenvolvedor com o script de background:
### Páginas de opções e outras Extensões de navegador podem conter vários tipos de páginas: * **Páginas de ação** são exibidas em um **menu suspenso quando o ícone da extensão** é clicado. * Páginas que a extensão irá **carregar em uma nova aba**. * **Páginas de Opções**: Esta página é exibida sobre a extensão quando clicada. No manifesto anterior, no meu caso, eu consegui acessar esta página em `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca` ou clicando:
Ao contrário da página de background, essas páginas não são persistentes, mas sim carregadas quando necessário. No entanto, todas elas podem **receber mensagens de scripts de conteúdo**. E todas têm **acesso total às APIs específicas da extensão**, na medida em que as permissões da extensão permitem. Juntando tudo, os contextos relevantes para extensões de navegador parecem assim:
### `permissions` & `host_permissions` **`permissions`** e **`host_permissions`** são entradas do `manifest.json` que indicarão **quais permissões** a extensão do navegador possui (armazenamento, localização...) e em **quais páginas da web**. Como as extensões de navegador podem ser tão **privilegiadas**, uma maliciosa ou comprometida pode permitir ao atacante **diferentes meios para roubar informações sensíveis e espionar o usuário**. Verifique como essas configurações funcionam e como elas podem ser abusadas em: {% content-ref url="browext-permissions-and-host_permissions.md" %} [browext-permissions-and-host\_permissions.md](browext-permissions-and-host\_permissions.md) {% endcontent-ref %} ### `content_security_policy` Uma **política de segurança de conteúdo** também pode ser declarada dentro do `manifest.json`. Se houver uma definida, ela pode ser **vulnerável**. A configuração padrão para páginas de extensões de navegador é bastante restritiva: ```bash script-src 'self'; object-src 'self'; ``` Para mais informações sobre CSP e possíveis bypasses, confira: {% content-ref url="../content-security-policy-csp-bypass/" %} [content-security-policy-csp-bypass](../content-security-policy-csp-bypass/) {% endcontent-ref %} ### `web_accessible_resources` para que uma página da web acesse uma página de uma Extensão de Navegador, uma página `.html` por exemplo, esta página precisa ser mencionada no campo **`web_accessible_resources`** do `manifest.json`.\ Por exemplo: ```javascript { ... "web_accessible_resources": [ { "resources": [ "images/*.png" ], "matches": [ "https://example.com/*" ] }, { "resources": [ "fonts/*.woff" ], "matches": [ "https://example.com/*" ] } ], ... } ``` Estas páginas são acessíveis em URLs como: ``` chrome-extension:///message.html ``` Nas extensões públicas, o **extension-id é acessível**:
No entanto, se o parâmetro `manifest.json` **`use_dynamic_url`** for usado, este **id pode ser dinâmico**. Ser permitido acessar essas páginas torna essas páginas **potencialmente vulneráveis a ClickJacking**: {% content-ref url="browext-clickjacking.md" %} [browext-clickjacking.md](browext-clickjacking.md) {% endcontent-ref %} {% hint style="success" %} Permitir que essas páginas sejam carregadas apenas pela extensão e não por URLs aleatórias poderia prevenir ataques de ClickJacking. {% endhint %} ### `externally_connectable` Conforme a [**documentação**](https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable), a propriedade `"externally_connectable"` do manifesto declara **quais extensões e páginas da web podem se conectar** à sua extensão através de [runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect) e [runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage). * Se a chave **`externally_connectable`** **não** for declarada no manifesto da sua extensão ou for declarada como **`"ids": ["*"]`**, **todas as extensões podem se conectar, mas nenhuma página da web pode se conectar**. * Se **IDs específicos forem especificados**, como em `"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`, **apenas aquelas aplicações** poderão se conectar. * Se **correspondências** forem especificadas, esses aplicativos da web poderão se conectar: ```json "matches": [ "https://*.google.com/*", "*://*.chromium.org/*", ``` * Se estiver especificado como vazio: **`"externally_connectable": {}`**, nenhum aplicativo ou página web poderá se conectar. Quanto **menos extensões e URLs** indicadas aqui, **menor será a superfície de ataque**. {% hint style="danger" %} Se uma página web **vulnerável a XSS ou takeover** estiver indicada em **`externally_connectable`**, um atacante poderá **enviar mensagens diretamente para o script de background**, contornando completamente o Content Script e seu CSP. Portanto, este é um **bypass muito poderoso**. {% endhint %} ## Comunicação Web **↔︎** Content Script Embora os ambientes de execução dos **content scripts e das páginas** que os hospedam sejam **isolados** um do outro, eles **compartilham acesso ao DOM da página**. Se a página deseja se comunicar com o content script, ou com a extensão através do content script, deve fazê-lo através do **DOM compartilhado**. ### Postar Mensagens {% code title="content-script.js" %} ```javascript var port = chrome.runtime.connect(); window.addEventListener("message", (event) => { // We only accept messages from ourselves if (event.source !== window) { return; } if (event.data.type && (event.data.type === "FROM_PAGE")) { console.log("Content script received: " + event.data.text); port.postMessage(event.data.text); } }, false); ``` {% endcode %} {% code title="example.js" %} ```javascript document.getElementById("theButton").addEventListener("click", () => { window.postMessage( {type : "FROM_PAGE", text : "Hello from the webpage!"}, "*"); }, false); ``` {% endcode %} Uma comunicação segura de Post Message deve verificar a autenticidade da mensagem recebida, isso pode ser feito verificando: * **`event.isTrusted`**: Isso é verdadeiro apenas se o evento foi acionado por uma ação do usuário * O script de conteúdo pode estar esperando uma mensagem apenas se o usuário realizar alguma ação * **domínio de origem**: Pode ser verificado contra uma lista de permissões de domínios. * Se um regex é usado, tenha muito cuidado * **Fonte**: `received_message.source !== window` pode ser usado para verificar se a mensagem foi **da mesma janela** onde o Script de Conteúdo está ouvindo. Os controles anteriores, mesmo que realizados, podem ser vulneráveis, então verifique na seguinte página **possíveis bypasses de Post Message**: {% content-ref url="../postmessage-vulnerabilities/" %} [postmessage-vulnerabilities](../postmessage-vulnerabilities/) {% endcontent-ref %} ### Iframe Outra possível forma de comunicação pode ser através de **URLs de Iframe**, você pode encontrar um exemplo em: {% content-ref url="browext-xss-example.md" %} [browext-xss-example.md](browext-xss-example.md) {% endcontent-ref %} ### DOM Isso não é "exatamente" uma forma de comunicação, mas a **web e o script de conteúdo terão acesso ao DOM da web**. Então, se o **script de conteúdo** está lendo alguma informação dele, **confiando no DOM da web**, a web poderia **modificar esses dados** (porque a web não deve ser confiável, ou porque a web é vulnerável a XSS) e **comprometer o Script de Conteúdo**. Você também pode encontrar um exemplo de um **XSS baseado em DOM para comprometer uma extensão de navegador** em: {% content-ref url="browext-xss-example.md" %} [browext-xss-example.md](browext-xss-example.md) {% endcontent-ref %} ## Informações Sensíveis na Memória/Código Se uma Extensão de Navegador armazena **informações sensíveis dentro de sua memória**, isso poderia ser **despejado** (especialmente em máquinas Windows) e **procurado** por essas informações. Portanto, a memória da Extensão de Navegador **não deve ser considerada segura** e **informações sensíveis** como credenciais ou frases mnemônicas **não devem ser armazenadas**. Claro, **não coloque informações sensíveis no código**, pois elas serão **públicas**. ## Comunicação Script de Conteúdo **↔︎** Script de Fundo Um Script de Conteúdo pode usar as funções [**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **ou** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage) para enviar uma mensagem **serializável em JSON de uso único**. Para lidar com a **resposta**, use a **Promise** retornada. No entanto, para compatibilidade com versões anteriores, você ainda pode passar um **callback** como o último argumento. Enviar uma solicitação de um **script de conteúdo** se parece com isso: ```javascript (async () => { const response = await chrome.runtime.sendMessage({greeting: "hello"}); // do something with response here, not outside the function console.log(response); })(); ``` Enviando uma solicitação da **extensão** (geralmente um **script de background**) para um script de conteúdo é semelhante, exceto que você precisa especificar para qual aba enviá-la. Este exemplo demonstra o envio de uma mensagem para o script de conteúdo na aba selecionada. ```javascript (async () => { const [tab] = await chrome.tabs.query({active: true, lastFocusedWindow: true}); const response = await chrome.tabs.sendMessage(tab.id, {greeting: "hello"}); // do something with response here, not outside the function console.log(response); })(); ``` No **lado receptor**, você precisa configurar um [**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **ouvinte de evento** para lidar com a mensagem. Isso parece o mesmo de um script de conteúdo ou página de extensão. ```javascript chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) { console.log(sender.tab ? "from a content script:" + sender.tab.url : "from the extension"); if (request.greeting === "hello") sendResponse({farewell: "goodbye"}); } ); ``` No exemplo acima, **`sendResponse()`** foi chamado de forma síncrona. Se você quiser usar `sendResponse()` de forma **assíncrona**, adicione `return true;` ao manipulador de eventos `onMessage`. > Se múltiplas páginas estiverem ouvindo eventos `onMessage`, **apenas a primeira a chamar `sendResponse()`** para um evento específico terá sucesso em enviar a resposta. Todas as outras respostas para aquele evento serão ignoradas. Para novas extensões, você deve preferir promessas em vez de callbacks. Se você estiver usando callbacks, o callback `sendResponse()` só é válido se usado de forma síncrona, ou se o manipulador de eventos retornar `true` para indicar que responderá de forma assíncrona. O callback da função `sendMessage()` será invocado automaticamente se nenhum manipulador retornar true ou se o callback `sendResponse()` for coletado como lixo. ## Carregando uma Extensão no Navegador 1. **Baixe** a Extensão do Navegador e descompacte 2. Vá para **`chrome://extensions/`** e **ative** o `Modo de Desenvolvedor` 3. Clique no botão **`Carregar descompactado`** No **Firefox**, vá para **`about:debugging#/runtime/this-firefox`** e clique no botão **`Carregar Complemento Temporário`**. ## Obtendo o código-fonte da loja A partir de [**aqui**](https://gist.github.com/paulirish/78d6c1406c901be02c2d): ### Opção 1: Download da extensão via linha de comando como zip e extração {% code overflow="wrap" %} ```bash extension_id=jifpbeccnghkjeaalbbjmodiffmgedin # change this ID curl -L -o "$extension_id.zip" "https://clients2.google.com/service/update2/crx?response=redirect&os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc" unzip -d "$extension_id-source" "$extension_id.zip" ``` {% endcode %} Obrigado ao crxviewer pelo [URL de download mágico](https://github.com/Rob--W/crxviewer/blob/6113c25e3569e1ec59365ad9a177aa97e2bcda61/src/cws\_pattern.js#L27-L74). ### Opção 2: Use o site CRX Viewer [https://robwu.nl/crxviewer/](https://robwu.nl/crxviewer/) ### Opção 3: Use a extensão CRX Viewer A [Chrome extension source viewer](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en) é open source ([repositório github](https://github.com/Rob--W/crxviewer)) e facilita muito esse processo. ### Opção 3: Visualizar fonte da extensão instalada localmente 1. Encontre o diretório de perfil local do Chrome. Abra `chrome://version/` e localize o campo "Caminho do Perfil:". Abra essa pasta. 2. Abra a subpasta `Extensions/` 3. Todas as suas extensões estão aqui, com código-fonte geralmente legível. #### Mapeamento entre IDs de extensões instaladas localmente e nomes * Em `about:extensions`, ative o Modo Desenvolvedor e você verá IDs sob cada entrada * Dentro das pastas `Extensions/`, o arquivo manifest.json tem um campo `name` legível ## Lista de Verificação de Auditoria de Segurança Embora as Extensões de Navegador tenham uma **superfície de ataque limitada**, algumas delas podem conter **vulnerabilidades** ou **melhorias de proteção potenciais**. As mais comuns são: * [ ] **Limite** o máximo possível as **`permissions`** solicitadas * [ ] **Limite** o máximo possível as **`host_permissions`** * [ ] Use uma **`content_security_policy`** **forte** * [ ] **Limite** o máximo possível o **`externally_connectable`**, se nenhum for necessário e possível, não deixe por padrão, especifique **`{}`** * [ ] Se **URL vulnerável a XSS ou a takeover** for mencionada aqui, um atacante poderá **enviar mensagens diretamente aos scripts de background**. Um bypass muito poderoso. * [ ] **Limite** o máximo possível os **`web_accessible_resources`**, até mesmo vazio se possível. * [ ] Se **`web_accessible_resources`** não for nenhum, verifique [**ClickJacking**](browext-clickjacking.md) * [ ] Se houver alguma **comunicação** da **extensão** para a **página web**, [**verifique vulnerabilidades de XSS**](browext-xss-example.md) causadas na comunicação. * [ ] Se Post Messages forem usados, verifique [**vulnerabilidades de Post Message**](../postmessage-vulnerabilities/)**.** * [ ] Se o **Content Script acessar detalhes do DOM**, verifique se eles **não estão introduzindo um XSS** se forem **modificados** pela web * [ ] Dê uma ênfase especial se essa comunicação também estiver envolvida na **comunicação Content Script -> Background script** * [ ] **Informações sensíveis não devem ser armazenadas** no código da Extensão de Navegador * [ ] **Informações sensíveis não devem ser armazenadas** na memória da Extensão de Navegador ## Ferramentas ### [**Tarnish**](https://thehackerblog.com/tarnish/) * Baixa qualquer extensão do Chrome a partir de um link fornecido da Chrome webstore. * **Visualizador de [**manifest.json**](https://developer.chrome.com/extensions/manifest)**: simplesmente exibe uma versão em JSON formatado do manifest da extensão. * **Análise de Impressão Digital**: Detecção de [web\_accessible\_resources](https://developer.chrome.com/extensions/manifest/web\_accessible\_resources) e geração automática de JavaScript para fingerprinting de extensões do Chrome. * **Análise Potencial de Clickjacking**: Detecção de páginas HTML de extensão com a diretiva [web\_accessible\_resources](https://developer.chrome.com/extensions/manifest/web\_accessible\_resources) definida. Estas são potencialmente vulneráveis a clickjacking, dependendo da finalidade das páginas. * **Visualizador de Aviso(s) de Permissão**: que mostra uma lista de todos os avisos de prompt de permissão do Chrome que serão exibidos quando um usuário tentar instalar a extensão. * **Função(ões) Perigosa(s)**: mostra a localização de funções perigosas que podem potencialmente ser exploradas por um atacante (por exemplo, funções como innerHTML, chrome.tabs.executeScript). * **Ponto(s) de Entrada**: mostra onde a extensão recebe entrada de usuário/externa. Isso é útil para entender a área de superfície de uma extensão e procurar pontos potenciais para enviar dados maliciosamente elaborados para a extensão. * Tanto o scanner de Função(ões) Perigosa(s) quanto o de Ponto(s) de Entrada têm o seguinte para seus alertas gerados: * Trecho de código relevante e linha que causou o alerta. * Descrição do problema. * Um botão "Ver Arquivo" para visualizar o arquivo de código completo. * O caminho do arquivo alertado. * A URI completa da extensão do Chrome do arquivo alertado. * O tipo de arquivo, como um script de Página de Fundo, Script de Conteúdo, Ação do Navegador, etc. * Se a linha vulnerável estiver em um arquivo JavaScript, os caminhos de todas as páginas onde está incluído, bem como o tipo dessas páginas e status de [web\_accessible\_resource](https://developer.chrome.com/extensions/manifest/web\_accessible\_resources). * **Analisador de Política de Segurança de Conteúdo (CSP) e verificador de bypass**: Isso apontará fraquezas na CSP da sua extensão e também iluminará quaisquer maneiras potenciais de contornar sua CSP devido a CDNs na lista branca, etc. * **Bibliotecas Conhecidas Vulneráveis**: Isso usa [Retire.js](https://retirejs.github.io/retire.js/) para verificar o uso de bibliotecas JavaScript conhecidas por serem vulneráveis. * Baixe a extensão e versões formatadas. * Baixe a extensão original. * Baixe uma versão embelezada da extensão (HTML e JavaScript automaticamente formatados). * Cache automático dos resultados da análise, executar uma análise de extensão levará um bom tempo na primeira vez que você executá-la. No entanto, a segunda vez, assumindo que a extensão não foi atualizada, será quase instantânea devido aos resultados serem armazenados em cache. * URLs de Relatório Linkáveis, facilmente vincule alguém a um relatório de extensão gerado pelo tarnish. ### [Neto](https://github.com/elevenpaths/neto) O projeto Neto é um pacote Python 3 concebido para analisar e desvendar recursos ocultos de plugins e extensões de navegadores bem conhecidos, como Firefox e Chrome. Ele automatiza o processo de descompactar os arquivos empacotados para extrair esses recursos de recursos relevantes em uma extensão como `manifest.json`, pastas de localização ou arquivos de fonte Javascript e HTML. ## Referências * **Agradecimentos a** [**@naivenom**](https://twitter.com/naivenom) **pela ajuda com esta metodologia** * [https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing](https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing) * [https://palant.info/2022/08/10/anatomy-of-a-basic-extension/](https://palant.info/2022/08/10/anatomy-of-a-basic-extension/) * [https://palant.info/2022/08/24/attack-surface-of-extension-pages/](https://palant.info/2022/08/24/attack-surface-of-extension-pages/) * [https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/](https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/) * [https://help.passbolt.com/assets/files/PBL-02-report.pdf](https://help.passbolt.com/assets/files/PBL-02-report.pdf) * [https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts](https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts) * [https://developer.chrome.com/docs/extensions/mv2/background-pages](https://developer.chrome.com/docs/extensions/mv2/background-pages) * [https://thehackerblog.com/kicking-the-rims-a-guide-for-securely-writing-and-auditing-chrome-extensions/](https://thehackerblog.com/kicking-the-rims-a-guide-for-securely-writing-and-auditing-chrome-extensions/)
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras formas de apoiar o HackTricks: * Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Adquira o [**merchandising oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos * **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Compartilhe suas dicas de hacking enviando PRs para os repositórios github** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).