.. | ||
browext-clickjacking.md | ||
browext-permissions-and-host_permissions.md | ||
browext-xss-example.md | ||
README.md |
Metodologia di Pentesting delle Estensioni del Browser
Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri La Famiglia PEASS, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR a HackTricks e HackTricks Cloud repos di github.
Informazioni di Base
Le estensioni del browser sono scritte in JavaScript e caricate dal browser in background. Hanno il loro DOM ma possono interagire con i DOM di altri siti. Ciò significa che potrebbero compromettere la confidenzialità, l'integrità e la disponibilità di altri siti (CIA).
Componenti Principali
I layout delle estensioni appaiono migliori quando visualizzati e sono composti da tre componenti. Esaminiamo ogni componente in dettaglio.
![](/Mirrors/hacktricks/media/commit/5ddc77514ef000c6cd591df010aa67ed1c3afda1/.gitbook/assets/image%20%2816%29%20%281%29.png)
Script di Contenuto
Ogni script di contenuto ha accesso diretto al DOM di una singola pagina web ed è quindi esposto a input potenzialmente dannosi. Tuttavia, lo script di contenuto non ha autorizzazioni diverse dalla capacità di inviare messaggi al core dell'estensione.
Core dell'Estensione
Il core dell'estensione contiene la maggior parte dei privilegi/accessi dell'estensione, ma il core dell'estensione può interagire solo con il contenuto web tramite XMLHttpRequest e script di contenuto. Inoltre, il core dell'estensione non ha accesso diretto alla macchina host.
Binario Nativo
L'estensione consente un binario nativo che può accedere alla macchina host con i pieni privilegi dell'utente. Il binario nativo interagisce con il core dell'estensione attraverso l'interfaccia di programmazione delle applicazioni del plugin Netscape standard (NPAPI) utilizzata da Flash e altri plugin del browser.
Limiti
{% hint style="danger" %} Per ottenere i pieni privilegi dell'utente, un attaccante deve convincere l'estensione a passare input dannosi dallo script di contenuto al core dell'estensione e dal core dell'estensione al binario nativo. {% endhint %}
Ogni componente dell'estensione è separato gli uni dagli altri da forti confini protettivi. Ogni componente viene eseguito in un processo separato del sistema operativo. Gli script di contenuto e i core delle estensioni vengono eseguiti in processi sandbox non disponibili alla maggior parte dei servizi del sistema operativo.
Inoltre, gli script di contenuto sono separati dalle rispettive pagine web eseguendo in un heap JavaScript separato. Lo script di contenuto e la pagina web hanno accesso allo stesso DOM sottostante, ma i due non scambiano mai puntatori JavaScript, impedendo la fuoriuscita di funzionalità JavaScript.
manifest.json
Un'estensione Chrome è semplicemente una cartella ZIP con estensione file .crx. Il core dell'estensione è il file manifest.json
nella radice della cartella, che specifica layout, autorizzazioni e altre opzioni di configurazione.
Esempio:
{
"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
I content scripts vengono caricati ogni volta che l'utente naviga su una pagina corrispondente, nel nostro caso su qualsiasi pagina corrispondente all'espressione https://example.com/*
e non corrispondente alla regex *://*/*/business*
. Eseguono come gli script della pagina stessa e hanno accesso arbitrario al Document Object Model (DOM) della pagina.
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
Per includere o escludere ulteriori URL è anche possibile utilizzare include_globs
e exclude_globs
.
Questo è un esempio di script di contenuto che aggiungerà un pulsante di spiegazione alla pagina quando l'API di storage per recuperare il valore message
dallo storage dell'estensione.
chrome.storage.local.get("message", result =>
{
let div = document.createElement("div");
div.innerHTML = result.message + " <button>Explain</button>";
div.querySelector("button").addEventListener("click", () =>
{
chrome.runtime.sendMessage("explain");
});
document.body.appendChild(div);
});
![](/Mirrors/hacktricks/media/commit/5ddc77514ef000c6cd591df010aa67ed1c3afda1/.gitbook/assets/image%20%2823%29.png)
Un messaggio viene inviato alle pagine dell'estensione dallo script di contenuto quando viene cliccato questo pulsante, attraverso l'utilizzo dell'API runtime.sendMessage(). Ciò è dovuto alla limitazione dello script di contenuto nell'accesso diretto alle API, con storage
tra le poche eccezioni. Per funzionalità al di là di queste eccezioni, vengono inviati messaggi alle pagine dell'estensione con cui gli script di contenuto possono comunicare.
{% hint style="warning" %}
A seconda del browser, le capacità dello script di contenuto possono variare leggermente. Per i browser basati su Chromium, l'elenco delle capacità è disponibile nella documentazione per sviluppatori di Chrome, e per Firefox, il MDN funge da fonte primaria.
È inoltre importante notare che gli script di contenuto hanno la capacità di comunicare con gli script di background, consentendo loro di eseguire azioni e trasmettere risposte.
{% endhint %}
Per visualizzare e eseguire il debug degli script di contenuto in Chrome, è possibile accedere al menu degli strumenti per sviluppatori di Chrome da Opzioni > Altri strumenti > Strumenti per sviluppatori OPPURE premendo Ctrl + Shift + I.
Una volta visualizzati gli strumenti per sviluppatori, è necessario fare clic sulla scheda Sorgente, seguita dalla scheda Script di contenuto. Ciò consente di osservare gli script di contenuto in esecuzione da varie estensioni e impostare i punti di interruzione per tracciare il flusso di esecuzione.
Script di contenuto iniettati
{% hint style="success" %}
Si noti che gli script di contenuto non sono obbligatori poiché è anche possibile iniettare dinamicamente script e iniettarli programmaticamente nelle pagine web tramite tabs.executeScript
. Questo fornisce effettivamente un controllo più granulare.
{% endhint %}
Per l'iniezione programmatica di uno script di contenuto, è necessario che l'estensione abbia le autorizzazioni dell'host per la pagina in cui gli script devono essere iniettati. Queste autorizzazioni possono essere garantite sia richiedendole all'interno del manifesto dell'estensione che su base temporanea tramite activeTab.
Esempio di estensione basata su activeTab
{% code title="manifest.json" %}
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
{% endcode %}
- Iniettare un file JS al clic:
// 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"]
});
});
- Iniettare una funzione al click:
//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,
});
});
Esempio con autorizzazioni di scripting
// service-workser.js
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
excludeMatches : [ "*://*/*business*" ],
js : [ "contentScript.js" ],
}]);
// Another example
chrome.tabs.executeScript(tabId, { file: "content_script.js" });
Per includere o escludere ulteriori URL è anche possibile utilizzare include_globs
e exclude_globs
.
Esecuzione degli script run_at
Il campo run_at
controlla quando i file JavaScript vengono iniettati nella pagina web. Il valore preferito e predefinito è "document_idle"
.
I valori possibili sono:
document_idle
: Quando possibiledocument_start
: Dopo eventuali file dacss
, ma prima che venga costruito qualsiasi altro DOM o venga eseguito qualsiasi altro script.document_end
: Immediatamente dopo il completamento del DOM, ma prima che vengano caricati sottorisorse come immagini e frame.
Attraverso manifest.json
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
Attraverso service-worker.js
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);
sfondo
I messaggi inviati dagli script di contenuto sono ricevuti dalla pagina di sfondo, che svolge un ruolo centrale nel coordinare i componenti dell'estensione. In particolare, la pagina di sfondo persiste per tutta la durata dell'estensione, operando discretamente senza interazione diretta dell'utente. Possiede il proprio Document Object Model (DOM), consentendo interazioni complesse e gestione dello stato.
Punti chiave:
- Ruolo della Pagina di Sfondo: Agisce come centro nervoso dell'estensione, garantendo comunicazione e coordinamento tra le varie parti dell'estensione.
- Persistenza: È un'entità sempre presente, invisibile per l'utente ma fondamentale per la funzionalità dell'estensione.
- Generazione Automatica: Se non è definita esplicitamente, il browser creerà automaticamente una pagina di sfondo. Questa pagina generata automaticamente includerà tutti gli script di sfondo specificati nel manifesto dell'estensione, garantendo il funzionamento senza intoppi dei compiti di sfondo dell'estensione.
{% hint style="success" %} La comodità fornita dal browser nella generazione automatica di una pagina di sfondo (quando non dichiarata esplicitamente) garantisce che tutti gli script di sfondo necessari siano integrati e operativi, semplificando il processo di configurazione dell'estensione. {% endhint %}
Esempio script di sfondo:
chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
{
if (request == "explain")
{
chrome.tabs.create({ url: "https://example.net/explanation" });
}
})
Utilizza l'API runtime.onMessage per ascoltare i messaggi. Quando viene ricevuto un messaggio "explain"
, utilizza l'API tabs per aprire una pagina in una nuova scheda.
Per eseguire il debug dello script di background, è possibile andare ai dettagli dell'estensione e ispezionare il service worker, questo aprirà gli strumenti per sviluppatori con lo script di background:
Pagine delle opzioni e altre
Le estensioni del browser possono contenere vari tipi di pagine:
- Le pagine di azione vengono visualizzate in un menu a discesa quando si fa clic sull'icona dell'estensione.
- Pagine che l'estensione caricherà in una nuova scheda.
- Pagine delle opzioni: Questa pagina viene visualizzata sopra l'estensione quando si fa clic. Nel manifesto precedente nel mio caso sono riuscito ad accedere a questa pagina in
chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca
o facendo clic su:
![](/Mirrors/hacktricks/media/commit/5ddc77514ef000c6cd591df010aa67ed1c3afda1/.gitbook/assets/image%20%2824%29.png)
Si noti che queste pagine non sono persistenti come le pagine di background poiché caricano dinamicamente il contenuto solo quando necessario. Nonostante ciò, condividono alcune capacità con la pagina di background:
- Comunicazione con gli script di contenuto: Similmente alla pagina di background, queste pagine possono ricevere messaggi dagli script di contenuto, facilitando l'interazione all'interno dell'estensione.
- Accesso alle API specifiche dell'estensione: Queste pagine godono di un accesso completo alle API specifiche dell'estensione, soggette alle autorizzazioni definite per l'estensione.
permissions
& host_permissions
permissions
e host_permissions
sono voci presenti nel manifest.json
che indicheranno quali autorizzazioni ha l'estensione del browser (archiviazione, posizione...) e in quali pagine web.
Poiché le estensioni del browser possono essere così privilegiate, una malintenzionata o compromessa potrebbe consentire all'attaccante diversi mezzi per rubare informazioni sensibili e spiare l'utente.
Verifica come funzionano queste impostazioni e come potrebbero essere abusate in:
{% content-ref url="browext-permissions-and-host_permissions.md" %} browext-permissions-and-host_permissions.md {% endcontent-ref %}
content_security_policy
Una policy di sicurezza dei contenuti può essere dichiarata anche all'interno del manifest.json
. Se ne è definita una, potrebbe essere vulnerabile.
L'impostazione predefinita per le pagine delle estensioni del browser è piuttosto restrittiva:
script-src 'self'; object-src 'self';
Per ulteriori informazioni su CSP e potenziali bypass, controlla:
{% content-ref url="../content-security-policy-csp-bypass/" %} content-security-policy-csp-bypass {% endcontent-ref %}
web_accessible_resources
affinché una pagina web possa accedere a una pagina di un'estensione del browser, ad esempio una pagina .html
, questa pagina deve essere menzionata nel campo web_accessible_resources
del manifest.json
.
Per esempio:
{
...
"web_accessible_resources": [
{
"resources": [ "images/*.png" ],
"matches": [ "https://example.com/*" ]
},
{
"resources": [ "fonts/*.woff" ],
"matches": [ "https://example.com/*" ]
}
],
...
}
Queste pagine sono accessibili tramite URL come:
chrome-extension://<extension-id>/message.html
In estensioni pubbliche l'ID dell'estensione è accessibile:
![](/Mirrors/hacktricks/media/commit/5ddc77514ef000c6cd591df010aa67ed1c3afda1/.gitbook/assets/image%20%281194%29.png)
Tuttavia, se il parametro manifest.json
use_dynamic_url
è utilizzato, questo ID può essere dinamico.
{% hint style="success" %} Nota che anche se una pagina è menzionata qui, potrebbe essere protetta contro il ClickJacking grazie alla Content Security Policy. Quindi è necessario controllare anche questo (sezione frame-ancestors) prima di confermare che un attacco di ClickJacking sia possibile. {% endhint %}
Essere autorizzati ad accedere a queste pagine rende queste pagine potenzialmente vulnerabili al ClickJacking:
{% content-ref url="browext-clickjacking.md" %} browext-clickjacking.md {% endcontent-ref %}
{% hint style="success" %} Consentire a queste pagine di essere caricate solo dall'estensione e non da URL casuali potrebbe prevenire gli attacchi di ClickJacking. {% endhint %}
{% hint style="danger" %}
Nota che le pagine da web_accessible_resources
e altre pagine dell'estensione sono in grado di contattare gli script di background. Quindi se una di queste pagine è vulnerabile a XSS potrebbe aprire una vulnerabilità più ampia.
Inoltre, nota che è possibile aprire solo le pagine indicate in web_accessible_resources
all'interno di iframe, ma da una nuova scheda è possibile accedere a qualsiasi pagina nell'estensione conoscendo l'ID dell'estensione. Pertanto, se viene trovato un XSS sfruttando gli stessi parametri, potrebbe essere sfruttato anche se la pagina non è configurata in web_accessible_resources
.
{% endhint %}
externally_connectable
Come da documentazione, la proprietà del manifesto "externally_connectable"
dichiara quali estensioni e pagine web possono connettersi alla tua estensione tramite runtime.connect e runtime.sendMessage.
- Se la chiave
externally_connectable
non è dichiarata nel manifesto della tua estensione o è dichiarata come"ids": ["*"]
, tutte le estensioni possono connettersi, ma nessuna pagina web può connettersi. - Se vengono specificati ID specifici, come in
"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
, solo quelle applicazioni possono connettersi. - Se vengono specificati corrispondenze, quelle app web saranno in grado di connettersi:
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
- Se è specificato come vuoto:
"externally_connectable": {}
, nessuna app o sito web potrà connettersi.
Più estensioni e URL sono indicati qui, più piccola sarà la superficie di attacco.
{% hint style="danger" %}
Se una pagina web vulnerabile a XSS o takeover è indicata in externally_connectable
, un attaccante potrà inviare messaggi direttamente allo script di background, bypassando completamente lo script di contenuto e la sua CSP.
Pertanto, si tratta di un bypass molto potente.
Inoltre, se il cliente installa un'estensione fraudolenta, anche se non è consentito comunicare con l'estensione vulnerabile, potrebbe iniettare dati XSS in una pagina web consentita o abusare delle API WebRequest
o DeclarativeNetRequest
per manipolare le richieste su un dominio mirato alterando la richiesta di un file JavaScript di una pagina. (Si noti che la CSP sulla pagina mirata potrebbe prevenire questi attacchi). Questa idea proviene da questo articolo.
{% endhint %}
Riassunto della comunicazione
Estensione <--> WebApp
Per comunicare tra lo script di contenuto e la pagina web di solito vengono utilizzati i messaggi post. Pertanto, nell'applicazione web troverai di solito chiamate alla funzione window.postMessage
e nello script di contenuto ascoltatori come window.addEventListener
. Tuttavia, l'estensione potrebbe anche comunicare con l'applicazione web inviando un messaggio post (e quindi il web dovrebbe aspettarselo) o semplicemente far caricare al web uno script nuovo.
All'interno dell'estensione
Di solito la funzione chrome.runtime.sendMessage
viene utilizzata per inviare un messaggio all'interno dell'estensione (gestito di solito dallo script background
) e per riceverlo e gestirlo viene dichiarato un ascoltatore chiamando chrome.runtime.onMessage.addListener
.
È anche possibile utilizzare chrome.runtime.connect()
per avere una connessione persistente invece di inviare singoli messaggi, è possibile utilizzarlo per inviare e ricevere messaggi come nell'esempio seguente:
Esempio di chrome.runtime.connect()
chrome.runtime.connect()
```javascript
var port = chrome.runtime.connect();
// Listen for messages from the web page
window.addEventListener("message", (event) => {
// Only accept messages from the same window
if (event.source !== window) {
return;
}
// Check if the message type is "FROM_PAGE"
if (event.data.type && (event.data.type === "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
// Forward the message to the background script
port.postMessage({ type: 'FROM_PAGE', text: event.data.text });
}
}, false);
// Listen for messages from the background script
port.onMessage.addListener(function(msg) {
console.log("Content script received message from background script:", msg);
// Handle the response message from the background script
});
</details>
È anche possibile inviare messaggi da uno script di background a uno script di contenuto situato in una scheda specifica chiamando **`chrome.tabs.sendMessage`** dove sarà necessario indicare l'**ID della scheda** a cui inviare il messaggio.
### Da `externally_connectable` consentito all'estensione
**Le app Web e le estensioni del browser esterne consentite** nella configurazione `externally_connectable` possono inviare richieste utilizzando:
```javascript
chrome.runtime.sendMessage(extensionId, ...
Dove è necessario menzionare l'ID dell'estensione.
Comunicazione Web ↔︎ Script del Contenuto
Gli ambienti in cui operano gli script del contenuto e dove esistono le pagine host sono separati l'uno dall'altro, garantendo isolamento. Nonostante questo isolamento, entrambi hanno la capacità di interagire con il Modello ad Oggetti del Documento (DOM) della pagina, una risorsa condivisa. Per consentire alla pagina host di comunicare con lo script del contenuto, o indirettamente con l'estensione attraverso lo script del contenuto, è necessario utilizzare il DOM accessibile da entrambe le parti come canale di comunicazione.
Messaggi di Posta
{% code title="script-del-contenuto.js" %}
// This is like "chrome.runtime.sendMessage" but to maintain the connection
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);
// Forward the message to the background script
port.postMessage(event.data.text);
}
}, false);
{% endcode %}
{% code title="esempio.js" %}
document.getElementById("theButton").addEventListener("click", () => {
window.postMessage(
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);
{% endcode %}
Una comunicazione sicura tramite Post Message dovrebbe verificare l'autenticità del messaggio ricevuto, questo può essere fatto controllando:
event.isTrusted
: Questo è True solo se l'evento è stato attivato da un'azione dell'utente
- Lo script di contenuto potrebbe aspettarsi un messaggio solo se l'utente esegue qualche azione
- Dominio di origine: potrebbe aspettarsi un messaggio solo da una lista di domini consentiti.
- Se viene utilizzata un'espressione regolare, fare molta attenzione
- Sorgente:
received_message.source !== window
può essere utilizzato per verificare se il messaggio proveniva dalla stessa finestra in cui lo script di contenuto sta ascoltando.
I controlli precedenti, anche se eseguiti, potrebbero essere vulnerabili, quindi controlla nella pagina seguente le possibili violazioni di Post Message:
{% content-ref url="../postmessage-vulnerabilities/" %}
postmessage-vulnerabilities
{% endcontent-ref %}
Iframe
Un altro possibile modo di comunicazione potrebbe essere attraverso URL Iframe, puoi trovare un esempio in:
{% content-ref url="browext-xss-example.md" %}
browext-xss-example.md
{% endcontent-ref %}
DOM
Questo non è "esattamente" un modo di comunicazione, ma il web e lo script di contenuto avranno accesso al DOM web. Quindi, se lo script di contenuto sta leggendo alcune informazioni da esso, affidandosi al DOM web, il web potrebbe modificare questi dati (perché il web non dovrebbe essere affidabile, o perché il web è vulnerabile a XSS) e compromettere lo script di contenuto.
Puoi trovare anche un esempio di XSS basato su DOM per compromettere un'estensione del browser in:
{% content-ref url="browext-xss-example.md" %}
browext-xss-example.md
{% endcontent-ref %}
Comunicazione tra Script di Contenuto ↔︎ Script di Background
Uno script di contenuto può utilizzare le funzioni runtime.sendMessage() o tabs.sendMessage() per inviare un messaggio una tantum serializzabile in JSON.
Per gestire la risposta, utilizza la Promise restituita. Tuttavia, per la compatibilità all'indietro, è ancora possibile passare un callback come ultimo argomento.
L'invio di una richiesta da uno script di contenuto appare così:
(async () => {
const response = await chrome.runtime.sendMessage({greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();
Inviare una richiesta dall'estensione (di solito uno script di background). Esempio di come inviare un messaggio allo script di contenuto nella scheda selezionata:
// From https://stackoverflow.com/questions/36153999/how-to-send-a-message-between-chrome-extension-popup-and-content-script
(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);
})();
Sul lato ricevente, è necessario impostare un runtime.onMessage ascoltatore di eventi per gestire il messaggio. Questo appare allo stesso modo da uno script di contenuto o da una pagina di estensione.
// From https://stackoverflow.com/questions/70406787/javascript-send-message-from-content-js-to-background-js
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"});
}
);
Nell'esempio evidenziato, sendResponse()
è stato eseguito in modo sincrono. Per modificare il gestore eventi onMessage
per l'esecuzione asincrona di sendResponse()
, è imperativo incorporare return true;
.
Una considerazione importante è che nei casi in cui più pagine sono impostate per ricevere eventi onMessage
, la prima pagina a eseguire sendResponse()
per un evento specifico sarà l'unica in grado di consegnare efficacemente la risposta. Eventuali risposte successive allo stesso evento non verranno prese in considerazione.
Nella creazione di nuove estensioni, la preferenza dovrebbe essere verso le promesse anziché i callback. Riguardo all'uso dei callback, la funzione sendResponse()
è considerata valida solo se viene eseguita direttamente all'interno del contesto sincrono, o se il gestore eventi indica un'operazione asincrona restituendo true
. Se nessuno dei gestori restituisce true
o se la funzione sendResponse()
viene rimossa dalla memoria (garbage-collected), il callback associato alla funzione sendMessage()
verrà attivato per impostazione predefinita.
Informazioni Sensibili in Memoria/Codice/Clipboard
Se un'estensione del browser memorizza informazioni sensibili all'interno della sua memoria, queste potrebbero essere estratte (specialmente nei computer Windows) e ricercate per tali informazioni.
Pertanto, la memoria dell'estensione del browser non dovrebbe essere considerata sicura e le informazioni sensibili come credenziali o frasi mnemoniche non dovrebbero essere memorizzate.
Naturalmente, non inserire informazioni sensibili nel codice, poiché saranno pubbliche.
Per estrarre la memoria dal browser potresti estrarre la memoria del processo o andare nelle impostazioni dell'estensione del browser cliccando su Ispeziona popup
-> Nella sezione Memoria
-> Fai uno snapshot
e CTRL+F
per cercare all'interno dello snapshot informazioni sensibili.
Inoltre, informazioni altamente sensibili come chiavi mnemoniche o password non dovrebbero essere consentite di essere copiate negli appunti (o almeno rimuoverle dagli appunti in pochi secondi) poiché i processi che monitorano gli appunti saranno in grado di ottenerle.
Caricare un'estensione nel Browser
- Scarica l'Estensione del Browser & scompattala
- Vai a
chrome://extensions/
e abilita la Modalità Sviluppatore
- Clicca sul pulsante
Carica non incaricato
In Firefox vai a about:debugging#/runtime/this-firefox
e clicca sul pulsante Carica componente aggiuntivo temporaneo
.
Ottenere il codice sorgente dallo store
Il codice sorgente di un'estensione Chrome può essere ottenuto attraverso vari metodi. Di seguito sono fornite spiegazioni dettagliate e istruzioni per ciascuna opzione.
Scarica Estensione come ZIP tramite Command Line
Il codice sorgente di un'estensione Chrome può essere scaricato come file ZIP usando la riga di comando. Questo comporta l'uso di curl
per recuperare il file ZIP da un URL specifico e quindi estrarre i contenuti del file ZIP in una directory. Ecco i passaggi:
- Sostituisci
"extension_id"
con l'effettivo ID dell'estensione.
- Esegui i seguenti comandi:
extension_id=your_extension_id # Replace with the actual extension 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"
Utilizzare il sito web CRX Viewer
Utilizzare l'estensione CRX Viewer
Un altro metodo conveniente è utilizzare il Chrome Extension Source Viewer, che è un progetto open-source. Può essere installato dal Chrome Web Store. Il codice sorgente del visualizzatore è disponibile nel suo repository GitHub.
Visualizzare il codice sorgente dell'estensione installata localmente
Anche le estensioni Chrome installate localmente possono essere ispezionate. Ecco come:
- Accedi alla directory del profilo locale di Chrome visitando
chrome://version/
e individuando il campo "Percorso del profilo".
- Naviga nella sottocartella
Extensions/
all'interno della directory del profilo.
- Questa cartella contiene tutte le estensioni installate, di solito con il loro codice sorgente in un formato leggibile.
Per identificare le estensioni, puoi mappare i loro ID ai nomi:
- Abilita la Modalità Sviluppatore nella pagina
about:extensions
per vedere gli ID di ciascuna estensione.
- All'interno della cartella di ciascuna estensione, il file
manifest.json
contiene un campo name
leggibile, che ti aiuta a identificare l'estensione.
Utilizzare un Archiviatore o Decompressore di File
Vai al Chrome Web Store e scarica l'estensione. Il file avrà estensione .crx
. Cambia l'estensione del file da .crx
a .zip
. Utilizza un qualsiasi archiviatore di file (come WinRAR, 7-Zip, ecc.) per estrarre i contenuti del file ZIP.
Utilizzare la Modalità Sviluppatore in Chrome
Apri Chrome e vai su chrome://extensions/
. Abilita "Modalità Sviluppatore" in alto a destra. Fai clic su "Carica estensione non pacchettizzata...". Naviga nella directory della tua estensione. Questo non scarica il codice sorgente, ma è utile per visualizzare e modificare il codice di un'estensione già scaricata o sviluppata.
Checklist di Audit della Sicurezza
Anche se le Estensioni del Browser hanno una superficie di attacco limitata, alcune di esse potrebbero contenere vulnerabilità o miglioramenti potenziali della sicurezza. Ecco le più comuni:
- Limitare il più possibile le
autorizzazioni
richieste
- Limitare il più possibile le
host_permissions
- Utilizzare una
content_security_policy
forte
- Limitare il più possibile gli
externally_connectable
, se non è necessario e possibile, non lasciarlo per impostazione predefinita, specificare {}
- Se un URL vulnerabile a XSS o a takeover è menzionato qui, un attaccante sarà in grado di inviare messaggi direttamente agli script di background. Molto potente bypass.
- Limitare il più possibile le
web_accessible_resources
, anche vuoto se possibile.
- Se
web_accessible_resources
non è nullo, controllare il ClickJacking
- Se avviene una qualsiasi comunicazione dall'estensione alla pagina web, controllare XSS vulnerabilità causate nella comunicazione.
- Se vengono utilizzati i Post Messages, controllare le vulnerabilità di Post Message.
- Se lo Script di Contenuto accede ai dettagli del DOM, controllare che non stiano introducendo un XSS se vengono modificati dalla pagina web
- Fare particolare attenzione se questa comunicazione è coinvolta anche nella comunicazione Script di Contenuto -> Script di Background
- Le informazioni sensibili non dovrebbero essere memorizzate all'interno del codice dell'Estensione del Browser
- Le informazioni sensibili non dovrebbero essere memorizzate all'interno della memoria dell'Estensione del Browser
Strumenti
Tarnish
- Estrae qualsiasi estensione Chrome da un link fornito dal Chrome webstore.
- Visualizzatore manifest.json: visualizza semplicemente una versione JSON formattata del manifesto dell'estensione.
- Analisi delle impronte digitali: Rilevamento delle web_accessible_resources e generazione automatica di JavaScript per l'impronta digitale dell'estensione Chrome.
- Analisi potenziale Clickjacking: Rilevamento delle pagine HTML dell'estensione con la direttiva web_accessible_resources impostata. Queste sono potenzialmente vulnerabili al clickjacking a seconda dello scopo delle pagine.
- Visualizzatore Avvertimenti di Autorizzazione: mostra un elenco di tutti gli avvisi di autorizzazione di Chrome che verranno visualizzati quando un utente cercherà di installare l'estensione.
- Funzioni Pericolose: mostra la posizione delle funzioni pericolose che potrebbero essere sfruttate da un attaccante (ad esempio funzioni come innerHTML, chrome.tabs.executeScript).
- Punti di Ingresso: mostra dove l'estensione accetta input dell'utente/esterno. Questo è utile per comprendere l'area di superficie di un'estensione e cercare potenziali punti per inviare dati malevoli all'estensione.
- Sia i scanner delle Funzioni Pericolose che dei Punti di Ingresso hanno quanto segue per i loro avvisi generati:
- Frammento di codice rilevante e linea che ha causato l'avviso.
- Descrizione del problema.
- Un pulsante "Visualizza File" per visualizzare il file sorgente completo contenente il codice.
- Il percorso del file segnalato.
- L'URI completo dell'estensione Chrome del file segnalato.
- Il tipo di file, come uno script di Pagina di Background, Script di Contenuto, Azione del Browser, ecc.
- Se la linea vulnerabile è in un file JavaScript, i percorsi di tutte le pagine in cui è inclusa nonché lo stato di web_accessible_resource di queste pagine.
- Analizzatore e verificatore di bypass della Content Security Policy (CSP): Questo evidenzierà le debolezze nella CSP della tua estensione e illuminerà eventuali modi potenziali per bypassare la tua CSP a causa di CDN in whitelist, ecc.
- Librerie Vulnerabili Conosciute: Utilizza Retire.js per controllare l'uso di librerie JavaScript conosciute come vulnerabili.
- Scarica l'estensione e le versioni formattate.
- Scarica l'estensione originale.
- Scarica una versione formattata dell'estensione (HTML e JavaScript autoformattati).
- Cache automatica dei risultati della scansione, eseguire una scansione dell'estensione richiederà molto tempo la prima volta che la esegui. Tuttavia, la seconda volta, assumendo che l'estensione non sia stata aggiornata, sarà quasi istantanea grazie alla cache dei risultati.
- URL di report collegabili, per collegare facilmente qualcun altro a un report sull'estensione generato da tarnish.
Neto
Il progetto Neto è un pacchetto Python 3 concepito per analizzare e svelare funzionalità nascoste di plugin e estensioni del browser per browser ben noti come Firefox e Chrome. Automatizza il processo di decomprimere i file confezionati per estrarre queste funzionalità da risorse rilevanti in un'estensione come manifest.json
, cartelle di localizzazione o file sorgente Javascript e HTML.
Riferimenti
- Grazie a @naivenom per l'aiuto con questa metodologia
- 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/24/attack-surface-of-extension-pages/
- https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/
- 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/mv2/background-pages
- https://thehackerblog.com/kicking-the-rims-a-guide-for-securely-writing-and-auditing-chrome-extensions/
- https://gist.github.com/LongJohnCoder/9ddf5735df3a4f2e9559665fb864eac0
Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri La Famiglia PEASS, la nostra collezione di esclusivi NFT
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repository di github.