hacktricks/pentesting-web/browser-extension-pentesting-methodology/README.md

678 lines
38 KiB
Markdown

# Metodologija testiranja bezbednosti proširenja pregledača
<details>
<summary><strong>Naučite hakovanje AWS-a od nule do heroja sa</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Drugi načini podrške HackTricks-u:
* Ako želite da vidite **vašu kompaniju reklamiranu na HackTricks-u** ili **preuzmete HackTricks u PDF formatu** proverite [**PLANOVE ZA PRIJAVU**](https://github.com/sponsors/carlospolop)!
* Nabavite [**zvanični PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Otkrijte [**Porodicu PEASS**](https://opensea.io/collection/the-peass-family), našu kolekciju ekskluzivnih [**NFT-ova**](https://opensea.io/collection/the-peass-family)
* **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili nas **pratite** na **Twitter-u** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Podelite svoje hakovanje trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
</details>
## Osnovne informacije
Proširenja pregledača su napisana u JavaScript-u i učitavaju se od strane pregledača u pozadini. Imaju svoj [DOM](https://www.w3schools.com/js/js\_htmldom.asp) ali mogu da interaguju sa DOM-ovima drugih sajtova. To znači da mogu ugroziti poverljivost, integritet i dostupnost (CIA) drugih sajtova.
## Glavne komponente
Dizajn proširenja izgleda najbolje kada je vizualizovan i sastoji se od tri komponente. Pogledajmo svaku komponentu detaljnije.
<figure><img src="../../.gitbook/assets/image (16) (1).png" alt=""><figcaption><p><a href="http://webblaze.cs.berkeley.edu/papers/Extensions.pdf">http://webblaze.cs.berkeley.edu/papers/Extensions.pdf</a></p></figcaption></figure>
### **Skripte sadržaja**
Svaka skripta sadržaja ima direktni pristup DOM-u **jedne veb stranice** i time je izložena **potencijalno zlonamernom unosu**. Međutim, skripta sadržaja ne sadrži dozvole osim mogućnosti slanja poruka jezgri proširenja.
### **Jezgro proširenja**
Jezgro proširenja sadrži većinu privilegija/pristupa proširenja, ali jezgro proširenja može interagovati sa veb sadržajem samo putem [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) i skripti sadržaja. Takođe, jezgro proširenja nema direktni pristup host mašini.
### **Nativni binarni fajl**
Proširenje omogućava nativni binarni fajl koji može **pristupiti host mašini sa punim privilegijama korisnika.** Nativni binarni fajl interaguje sa jezgrom proširenja putem standardnog Netscape Plugin Application Programming Interface ([NPAPI](https://en.wikipedia.org/wiki/NPAPI)) koji koristi Flash i druge dodatke pregledača.
### Granice
{% hint style="danger" %}
Da bi dobio puna korisnička prava, napadač mora ubediti proširenje da prosledi zlonameran unos iz skripte sadržaja jezgru proširenja i iz jezgra proširenja nativnom binarnom fajlu.
{% endhint %}
Svaka komponenta proširenja je odvojena jedna od druge **jakim zaštitnim granicama**. Svaka komponenta se izvršava u **zasebnom operativnom sistemu**. Skripte sadržaja i jezgra proširenja se izvršavaju u **peskovitim procesima** nedostupnim većini usluga operativnog sistema.
Pored toga, skripte sadržaja su odvojene od svojih povezanih veb stranica **izvršavanjem u zasebnom JavaScript hipu**. Skripta sadržaja i veb stranica imaju **pristup istom osnovnom DOM-u**, ali se **nikada ne razmenjuju JavaScript pokazivači**, čime se sprečava curenje JavaScript funkcionalnosti.
## **`manifest.json`**
Chrome proširenje je samo ZIP folder sa [.crx ekstenzijom fajla](https://www.lifewire.com/crx-file-2620391). Jezgro proširenja je **`manifest.json`** fajl na korenu foldera, koji specificira dizajn, dozvole i druge konfiguracione opcije.
Primer:
```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`
Sadržajni skriptovi se **učitavaju** svaki put kada korisnik **navigira na odgovarajuću stranicu**, u našem slučaju bilo koju stranicu koja odgovara izrazu **`https://example.com/*`** i ne odgovara regexu **`*://*/*/business*`**. Oni se izvršavaju **kao skriptovi same stranice** i imaju proizvoljan pristup [Document Object Model (DOM)](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) stranice.
```json
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
```
Da biste uključili ili isključili više URL-ova, takođe je moguće koristiti **`include_globs`** i **`exclude_globs`**.
Ovo je primer skripte sadržaja koja će dodati dugme za objašnjenje na stranici kada [API za skladištenje](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage) koristi se za dobijanje vrednosti `message` iz skladišta proširenja.
```js
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);
});
```
<figure><img src="../../.gitbook/assets/image (23).png" alt=""><figcaption></figcaption></figure>
Kada se klikne na ovaj dugme, poruka se šalje stranicama proširenja putem koda skripta sadržaja, korišćenjem [**API-ja runtime.sendMessage()**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage). Ovo je zbog ograničenja koda skripta sadržaja u direktnom pristupu API-ima, pri čemu je `storage` među retkim izuzecima. Za funkcionalnosti van ovih izuzetaka, poruke se šalju stranicama proširenja sa kojima skriptovi sadržaja mogu komunicirati.
{% hint style="warning" %}
Zavisno od pretraživača, mogućnosti koda skripta sadržaja mogu se blago razlikovati. Za pretraživače zasnovane na Chromium-u, lista mogućnosti dostupna je u [Chrome Developers dokumentaciji](https://developer.chrome.com/docs/extensions/mv3/content\_scripts/#capabilities), a za Firefox, [MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content\_scripts#webextension\_apis) služi kao primarni izvor.\
Takođe je važno napomenuti da skriptovi sadržaja imaju mogućnost komunikacije sa pozadinskim skriptovima, omogućavajući im da izvrše radnje i prenesu odgovore nazad.
{% endhint %}
Za pregledanje i debagovanje skriptova sadržaja u Chrome-u, meni Chrome developer alatki može se pristupiti putem Opcije > Više alatki > Alatke za razvoj OR pritiskom na Ctrl + Shift + I.
Kada se prikažu alatke za razvoj, treba kliknuti na **Tab izvora**, a zatim na **Tab skriptova sadržaja**. Ovo omogućava posmatranje pokrenutih skriptova sadržaja iz različitih proširenja i postavljanje tačaka prekida kako bi se pratilo izvršavanje toka.
### Ubaceni skriptovi sadržaja
{% hint style="success" %}
Imajte na umu da **Skriptovi sadržaja nisu obavezni** jer je takođe moguće **dinamički** **ubaciti** skriptove i **programatski ih ubaciti** na veb stranice putem **`tabs.executeScript`**. Ovo zapravo pruža više **granularnih kontrola**.
{% endhint %}
Za programatsko ubacivanje skripta sadržaja, proširenju je potrebno imati [dozvole domaćina](https://developer.chrome.com/docs/extensions/reference/permissions) za stranicu u koju se skriptovi ubacuju. Ove dozvole mogu se obezbediti ili **zahtevanjem** u manifestu proširenja ili privremeno putem [**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab).
#### Primer proširenja zasnovanog na activeTab-u
{% code title="manifest.json" %}
```json
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
```
{% endcode %}
* **Umetnite JS fajl pritiskom na dugme:**
```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"]
});
});
```
* **Ubacivanje funkcije** na klik:
```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,
});
});
```
#### Primer sa dozvolama skriptovanja
```javascript
// 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" });
```
Da biste uključili ili isključili više URL-ova, takođe je moguće koristiti **`include_globs`** i **`exclude_globs`**.
### Skripte sadržaja `run_at`
Polje `run_at` kontroliše **kada se JavaScript fajlovi ubacuju u web stranicu**. Preferirana i podrazumevana vrednost je `"document_idle"`.
Moguće vrednosti su:
* **`document_idle`**: Kada god je moguće
* **`document_start`**: Nakon bilo kojih fajlova iz `css`, ali pre nego što je konstruisan bilo koji drugi DOM ili pokrenut bilo koji drugi skript.
* **`document_end`**: Neposredno nakon što je DOM kompletan, ali pre nego što su se učitale podređene resurse poput slika i frejmova.
#### Putem `manifest.json`
```json
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
```
Preko **`service-worker.js`**
```javascript
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);
```
### `pozadina`
Poruke poslate od strane skriptova sadržaja primaju se od strane **pozadinske stranice**, koja ima centralnu ulogu u koordinaciji komponenti proširenja. Posebno, pozadinska stranica perzistira tokom trajanja proširenja, diskretno funkcionišući bez direktnog korisničkog interakcije. Poseduje svoj Document Object Model (DOM), omogućavajući kompleksne interakcije i upravljanje stanjem.
**Ključne tačke**:
* **Uloga pozadinske stranice:** Deluje kao nervni centar proširenja, osiguravajući komunikaciju i koordinaciju među različitim delovima proširenja.
* **Perzistencija:** To je stalno prisutno entitet, nevidljivo korisniku ali integralno za funkcionalnost proširenja.
* **Automatsko generisanje:** Ako nije eksplicitno definisana, pretraživač će automatski kreirati pozadinsku stranicu. Ova automatski generisana stranica će uključiti sve pozadinske skripte navedene u manifestu proširenja, osiguravajući besprekorno funkcionisanje pozadinskih zadataka proširenja.
{% hint style="success" %}
Praktičnost koju pruža pretraživač automatskim generisanjem pozadinske stranice (kada nije eksplicitno navedeno) osigurava da su sve neophodne pozadinske skripte integrisane i operativne, olakšavajući proces postavljanja proširenja.
{% endhint %}
Primer pozadinske skripte:
```js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
{
if (request == "explain")
{
chrome.tabs.create({ url: "https://example.net/explanation" });
}
})
```
Koristi [runtime.onMessage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage) da bi osluškivao poruke. Kada primi poruku `"explain"`, koristi [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) da otvori stranicu u novom tabu.
Za debagovanje pozadinskog skripta možete otići na **detalje proširenja i pregledati servisni radnik**, što će otvoriti alatke za razvoj sa pozadinskim skriptom:
<figure><img src="https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/browser-extension-pentesting-methodology/broken-reference" alt=""><figcaption></figcaption></figure>
### Stranice opcija i ostalo
Browser ekstenzije mogu sadržati različite vrste stranica:
* **Stranice akcija** se prikazuju u **padajućem meniju kada se klikne ikona ekstenzije**.
* Stranice koje će se **učitati u novom tabu**.
* **Stranice opcija**: Ova stranica se prikazuje iznad ekstenzije kada se klikne. U prethodnom manifestu u mom slučaju mogao sam pristupiti ovoj stranici na `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca` ili klikom na:
<figure><img src="../../.gitbook/assets/image (24).png" alt="" width="375"><figcaption></figcaption></figure>
Imajte na umu da ove stranice nisu trajne poput pozadinskih stranica jer dinamički učitavaju sadržaj po potrebi. Ipak, dele određene mogućnosti sa pozadinskom stranicom:
* **Komunikacija sa skriptovima sadržaja:** Slično kao pozadinska stranica, ove stranice mogu primati poruke od skriptova sadržaja, olakšavajući interakciju unutar ekstenzije.
* **Pristup API-jima specifičnim za ekstenziju:** Ove stranice imaju sveobuhvatan pristup API-jima specifičnim za ekstenziju, podložan dozvolama definisanim za ekstenziju.
### `permissions` & `host_permissions`
**`permissions`** i **`host_permissions`** su unosi iz `manifest.json` koji će ukazati na **koje dozvole** browser ekstenzija ima (skladište, lokacija...) i na **kojim veb stranicama**.
Kako browser ekstenzije mogu biti tako **privilegovane**, zlonamerna ili kompromitovana ekstenzija može omogućiti napadaču **različite načine za krađu osetljivih informacija i špijuniranje korisnika**.
Proverite kako ove postavke funkcionišu i kako mogu biti zloupotrebljene u:
{% 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`
**Politika bezbednosti sadržaja** takođe može biti deklarisana unutar `manifest.json`. Ako je definisana, može biti **ranjiva**.
Podrazumevana postavka za stranice browser ekstenzija je prilično restriktivna:
```bash
script-src 'self'; object-src 'self';
```
Za više informacija o CSP i potencijalnim prevarama proverite:
{% content-ref url="../content-security-policy-csp-bypass/" %}
[content-security-policy-csp-bypass](../content-security-policy-csp-bypass/)
{% endcontent-ref %}
### `web_accessible_resources`
da bi veb stranica mogla da pristupi stranici Browser proširenja, na primer `.html` stranici, ova stranica mora biti navedena u polju **`web_accessible_resources`** u `manifest.json` fajlu.\
Na primer:
```javascript
{
...
"web_accessible_resources": [
{
"resources": [ "images/*.png" ],
"matches": [ "https://example.com/*" ]
},
{
"resources": [ "fonts/*.woff" ],
"matches": [ "https://example.com/*" ]
}
],
...
}
```
Ove stranice su dostupne na URL adresi poput:
```
chrome-extension://<extension-id>/message.html
```
U javnim ekstenzijama **ID ekstenzije je dostupan**:
<figure><img src="../../.gitbook/assets/image (1194).png" alt="" width="375"><figcaption></figcaption></figure>
Međutim, ako se koristi parametar `manifest.json` **`use_dynamic_url`**, ovaj **ID može biti dinamičan**.
{% hint style="success" %}
Imajte na umu da čak i ako je stranica navedena ovde, može biti **zaštićena od ClickJacking-a** zahvaljujući **Politici bezbednosti sadržaja**. Stoga je potrebno proveriti (odeljak frame-ancestors) pre potvrđivanja da je ClickJacking napad moguć.
{% endhint %}
Dozvola pristupa ovim stranicama čini ih **potencijalno ranjivim na ClickJacking**:
{% content-ref url="browext-clickjacking.md" %}
[browext-clickjacking.md](browext-clickjacking.md)
{% endcontent-ref %}
{% hint style="success" %}
Dozvoljavanje učitavanja ovih stranica samo od strane ekstenzije, a ne od nasumičnih URL-ova, može sprečiti napade ClickJacking.
{% endhint %}
{% hint style="danger" %}
Imajte na umu da stranice iz **`web_accessible_resources`** i druge stranice ekstenzije takođe mogu **kontaktirati pozadinske skripte**. Dakle, ako je jedna od ovih stranica ranjiva na **XSS**, to bi moglo otvoriti veću ranjivost.
Osim toga, imajte na umu da se stranice navedene u **`web_accessible_resources`** mogu otvoriti samo unutar iframes-a, ali iz novog taba je moguće pristupiti bilo kojoj stranici u ekstenziji znajući ID ekstenzije. Stoga, ako se pronađe XSS zloupotrebom istih parametara, to bi se moglo zloupotrebiti čak i ako stranica nije konfigurisana u **`web_accessible_resources`**.
{% endhint %}
### `externally_connectable`
Prema [**dokumentaciji**](https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable), svojstvo manifesta `"externally_connectable"` deklariše **koje ekstenzije i web stranice mogu da se povežu** sa vašom ekstenzijom putem [runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect) i [runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage).
* Ako ključ **`externally_connectable`** nije deklarisan u manifestu vaše ekstenzije ili je deklarisan kao **`"ids": ["*"]`**, **sve ekstenzije mogu da se povežu, ali nijedna web stranica ne može**.
* Ako su **specifični ID-ovi navedeni**, kao u `"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`, **samo te aplikacije** mogu da se povežu.
* Ako su navedeni **odgovarajući podudarnosti**, te veb aplikacije će moći da se povežu:
```json
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
```
* Ako je navedeno kao prazno: **`"externally_connectable": {}`**, nijedna aplikacija ili veb stranica neće moći da se poveže.
Što je manje proširenja i URL-ova navedeno ovde, to će površina napada biti manja.
{% hint style="danger" %}
Ako je veb stranica ranjiva na XSS ili preuzimanje kontrole navedena u **`externally_connectable`**, napadač će moći da šalje poruke direktno skriptu pozadine, potpuno zaobilazeći Skript sadržaja i njegov CSP.
Stoga, ovo je veoma moćna zaobilaznica.
Štaviše, ako klijent instalira zlonamerno proširenje, čak i ako mu nije dozvoljeno da komunicira sa ranjivim proširenjem, moglo bi da ubaci XSS podatke na dozvoljenu veb stranicu ili zloupotrebi `WebRequest` ili `DeclarativeNetRequest` API-jeve da manipuliše zahtevima na ciljanoj domeni menjajući zahtev za stranicu za JavaScript fajl. (Imajte na umu da CSP na ciljanoj stranici može da spreči ove napade). Ova ideja potiče [**iz ovog teksta**](https://www.darkrelay.com/post/opera-zero-day-rce-vulnerability).
{% endhint %}
## Sažetak komunikacije
### Proširenje <--> Veb aplikacija
Za komunikaciju između skripta sadržaja i veb stranice obično se koriste poruke. Stoga, u veb aplikaciji obično ćete pronaći pozive funkcije **`window.postMessage`**, a u skriptu sadržaja slušače poput **`window.addEventListener`**. Međutim, proširenje takođe može **komunicirati sa veb aplikacijom slanjem Post Message-a** (i stoga veb treba da očekuje to) ili jednostavno učiniti da veb učita novi skript.
### Unutar proširenja
Obično se funkcija **`chrome.runtime.sendMessage`** koristi za slanje poruke unutar proširenja (obično obrađeno od strane skripta `background`) i kako bi je primilo i obradilo, deklariše se slušalac pozivajući **`chrome.runtime.onMessage.addListener`**.
Takođe je moguće koristiti **`chrome.runtime.connect()`** da bi se imala trajna veza umesto slanja pojedinačnih poruka, moguće je koristiti je za **slanje** i **primanje** **poruka** kao u sledećem primeru:
<details>
<summary><code>chrome.runtime.connect()</code> primer</summary>
```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>
Takođe je moguće slati poruke iz pozadinskog skripta ka sadržajnom skriptu koji se nalazi u određenom tabu pozivajući **`chrome.tabs.sendMessage`** gde ćete morati navesti **ID taba** kojem šaljete poruku.
### Od dozvoljenih `externally_connectable` ka ekstenziji
**Veb aplikacije i eksterni browser ekstenzije koje su dozvoljene** u konfiguraciji `externally_connectable` mogu slati zahteve koristeći:
```javascript
chrome.runtime.sendMessage(extensionId, ...
```
Gde je potrebno pomenuti **ID proširenja**.
## Komunikacija između veb **↔︎** skripte sadržaja
Okruženja u kojima **skripte sadržaja** funkcionišu i gde postoje stranice domaćini su **odvojena** jedno od drugog, obezbeđujući **izolaciju**. Uprkos ovoj izolaciji, oba imaju mogućnost da interaguju sa **Document Object Model (DOM)** stranice, deljenim resursom. Da bi domaća stranica stupila u komunikaciju sa **skriptom sadržaja**, ili neizravno sa proširenjem preko skripte sadržaja, potrebno je koristiti **DOM** koji je dostupan obema stranama kao kanal komunikacije.
### Slanje poruka
{% code title="skripta-sadrzaja.js" %}
```javascript
// 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="primer.js" %}
```javascript
document.getElementById("theButton").addEventListener("click", () => {
window.postMessage(
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);
```
{% endcode %}
Bezbedna komunikacija putem Post Message-a treba da proveri autentičnost primljene poruke, ovo se može uraditi proverom:
* **`event.isTrusted`**: Ovo je tačno samo ako je događaj pokrenut akcijom korisnika
* Skript za sadržaj može očekivati poruku samo ako korisnik izvrši neku akciju
* **Poreklo domena**: može očekivati poruku samo od liste odobrenih domena.
* Ako se koristi regex, budite veoma oprezni
* **Izvor**: `received_message.source !== window` može se koristiti da se proveri da li je poruka **sa istog prozora** gde Skript za Sadržaj sluša.
Prethodne provere, čak i ako su izvršene, mogu biti ranjive, pa proverite na sledećoj stranici **potencijalne Post Message zaobilaze**:
{% content-ref url="../postmessage-vulnerabilities/" %}
[postmessage-vulnerabilities](../postmessage-vulnerabilities/)
{% endcontent-ref %}
### Iframe
Još jedan mogući način komunikacije može biti putem **Iframe URL-ova**, možete pronaći primer u:
{% content-ref url="browext-xss-example.md" %}
[browext-xss-example.md](browext-xss-example.md)
{% endcontent-ref %}
### DOM
Ovo nije "tačno" način komunikacije, ali **web i skript za sadržaj će imati pristup web DOM-u**. Dakle, ako **skript za sadržaj** čita neke informacije iz njega, **verujući web DOM-u**, web bi mogao **modifikovati te podatke** (jer web ne bi trebalo da se veruje, ili jer je web ranjiv na XSS) i **ugroziti Skript za Sadržaj**.
Takođe možete pronaći primer **DOM baziranog XSS za ugrožavanje proširenja pregledača** u:
{% content-ref url="browext-xss-example.md" %}
[browext-xss-example.md](browext-xss-example.md)
{% endcontent-ref %}
## Komunikacija Skripta za Sadržaj **↔︎** Skripta Pozadine
Skript za Sadržaj može koristiti funkcije [**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **ili** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage) da pošalje **jednokratnu JSON-serializabilnu** poruku.
Za rukovanje **odgovorom**, koristite vraćeni **Promise**. Iako, radi kompatibilnosti unazad, i dalje možete proslediti **callback** kao poslednji argument.
Slanje zahteva iz **skripta za sadržaj** izgleda ovako:
```javascript
(async () => {
const response = await chrome.runtime.sendMessage({greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();
```
Slanje zahteva iz **ekstenzije** (obično iz **pozadinskog skripta**). Primer kako poslati poruku skriptu sadržaja na izabranoj kartici:
```javascript
// 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);
})();
```
Na **primalacu**, treba da postavite [**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **slušaoca događaja** da biste obradili poruku. Ovo izgleda isto iz sadržajnog skripta ili stranice proširenja.
```javascript
// 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"});
}
);
```
U prikazanom primeru, **`sendResponse()`** je izvršen sinhrono. Da biste izmenili `onMessage` rukovaoca događajima za asinhrono izvršavanje `sendResponse()`, imperativno je uključiti `return true;`.
Važno je imati na umu da u scenarijima gde je više stranica postavljeno da primaju `onMessage` događaje, **prva stranica koja izvrši `sendResponse()`** za određeni događaj će biti jedina sposobna da efikasno dostavi odgovor. Svi naknadni odgovori na isti događaj neće biti uzeti u obzir.
Prilikom kreiranja novih proširenja, prednost treba dati promisima umesto povratnim pozivima. Što se tiče korišćenja povratnih poziva, funkcija `sendResponse()` se smatra validnom samo ako se izvršava direktno unutar sinhronog konteksta, ili ako rukovalac događajem ukazuje na asinhronu operaciju vraćanjem `true`. Ukoliko nijedan od rukovalaca ne vrati `true` ili ako se funkcija `sendResponse()` ukloni iz memorije (sakupljena smećem), podrazumevano će biti pokrenut povratni poziv povezan sa funkcijom `sendMessage()`.
## Osetljive informacije u memoriji/kodu/klipbordu
Ako Browser proširenje čuva **osetljive informacije unutar svoje memorije**, ove informacije mogu biti **izvučene** (posebno na Windows mašinama) i **pretražene** za te informacije.
Stoga, memorija Browser proširenja **ne bi trebalo da se smatra bezbednom** i **osetljive informacije** poput akreditacija ili mnemoničkih fraza **ne bi trebalo da se čuvaju**.
Naravno, **ne stavljajte osetljive informacije u kod**, jer će biti **javne**.
Da biste izvukli memoriju iz browsera, možete **izvući memoriju procesa** ili otići na **postavke** browser proširenja i kliknuti na **`Inspect pop-up`** -> U odeljku **`Memory`** -> **`Napravite snimak`** i **`CTRL+F`** za pretragu unutar snimka za osetljive informacije.
Osim toga, visoko osetljive informacije poput mnemoničkih ključeva ili lozinki **ne bi trebalo da bude dozvoljeno kopiranje u klipbord** (ili bar uklonite ih iz klipborda za nekoliko sekundi) jer će procesi koji prate klipbord biti u mogućnosti da ih dobiju.
## Učitavanje proširenja u browseru
1. **Preuzmite** Browser proširenje i raspakujte ga
2. Idite na **`chrome://extensions/`** i **omogućite** `Developer Mode`
3. Kliknite na dugme **`Load unpacked`**
U **Firefox-u** idite na **`about:debugging#/runtime/this-firefox`** i kliknite na dugme **`Load Temporary Add-on`**.
## Dobijanje izvornog koda iz prodavnice
Izvorni kod Chrome proširenja može se dobiti putem različitih metoda. U nastavku su detaljna objašnjenja i uputstva za svaku opciju.
### Preuzimanje proširenja kao ZIP putem komandne linije
Izvorni kod Chrome proširenja može se preuzeti kao ZIP datoteka korišćenjem komandne linije. To uključuje korišćenje `curl`-a za preuzimanje ZIP datoteke sa određenog URL-a, a zatim izvlačenje sadržaja ZIP datoteke u direktorijum. Evo koraka:
1. Zamenite `"extension_id"` sa stvarnim ID-om proširenja.
2. Izvršite sledeće komande:
```bash
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"
```
### Koristite veb sajt CRX Viewer
[https://robwu.nl/crxviewer/](https://robwu.nl/crxviewer/)
### Koristite CRX Viewer ekstenziju
Još jedan praktičan metod je korišćenje Chrome Extension Source Viewer, koji je projekat otvorenog koda. Može se instalirati sa [Chrome Web prodavnice](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en). Izvorni kod pregledača je dostupan u njegovom [GitHub repozitorijumu](https://github.com/Rob--W/crxviewer).
### Pregled izvora lokalno instalirane ekstenzije
Lokalno instalirane Chrome ekstenzije takođe mogu biti pregledane. Evo kako:
1. Pristupite svom Chrome lokalnom profil direktorijumu posetom `chrome://version/` i pronalaženjem polja "Profile Path".
2. Navigirajte do poddirektorijuma `Extensions/` unutar profil direktorijuma.
3. Ovaj folder sadrži sve instalirane ekstenzije, obično sa njihovim izvornim kodom u čitljivom formatu.
Da biste identifikovali ekstenzije, možete mapirati njihove ID-jeve sa imenima:
* Omogućite Developer Mode na stranici `about:extensions` da biste videli ID-jeve svake ekstenzije.
* Unutar foldera svake ekstenzije, fajl `manifest.json` sadrži čitljivo polje `name`, pomažući vam da identifikujete ekstenziju.
### Koristite Arhiver ili Dekompresor fajlova
Idite na Chrome Web prodavnicu i preuzmite ekstenziju. Fajl će imati ekstenziju `.crx`. Promenite ekstenziju fajla sa `.crx` na `.zip`. Koristite bilo koji arhiver fajlova (kao što su WinRAR, 7-Zip, itd.) da biste izvukli sadržaj ZIP fajla.
### Koristite Developer Mode u Chrome-u
Otvorite Chrome i idite na `chrome://extensions/`. Omogućite "Developer mode" u gornjem desnom uglu. Kliknite na "Load unpacked extension...". Navigirajte do direktorijuma vaše ekstenzije. Ovo ne preuzima izvorni kod, ali je korisno za pregledanje i modifikaciju koda već preuzete ili razvijene ekstenzije.
## Lista za proveru bezbednosti
Iako Browser ekstenzije imaju **ograničenu površinu napada**, neke od njih mogu sadržati **ranjivosti** ili **potencijalna poboljšanja učvršćivanja**. Sledeće su najčešće:
* [ ] **Ograničite** što je više moguće tražene **`dozvole`**
* [ ] **Ograničite** što je više moguće **`host_permissions`**
* Koristite **jaku** **`content_security_policy`**
* [ ] **Ograničite** što je više moguće **`externally_connectable`**, ako nije potrebno i moguće, ne ostavljajte ga podrazumevano, specificirajte **`{}`**
* Ako je ovde naveden **URL ranjiv na XSS ili preuzimanje kontrole**, napadač će moći **slati poruke direktno skriptovima pozadine**. Veoma moćan zaobilazak.
* [ ] **Ograničite** što je više moguće **`web_accessible_resources`**, čak i prazno ako je moguće.
* Ako **`web_accessible_resources`** nije ništa, proverite [**ClickJacking**](browext-clickjacking.md)
* Ako se vrši bilo kakva **komunikacija** između **ekstenzije** i **veb stranice**, [**proverite XSS**](browext-xss-example.md) **ranjivosti** izazvane u komunikaciji.
* Ako se koriste Post poruke, proverite [**Post Message ranjivosti**](../postmessage-vulnerabilities/)**.**
* Ako **Content Script pristupa detaljima DOM-a**, proverite da li oni **ne uvode XSS** ako ih veb **modifikuje**
* Posebno obratite pažnju ako je ova komunikacija takođe uključena u **komunikaciju između Content Script-a i skripte pozadine**
* **Osetljive informacije ne bi trebalo da se čuvaju** unutar koda Browser ekstenzije
* **Osetljive informacije ne bi trebalo da se čuvaju** unutar memorije Browser ekstenzije
## Alati
### [**Tarnish**](https://thehackerblog.com/tarnish/)
* Preuzima bilo koju Chrome ekstenziju sa datog Chrome web prodavnice linka.
* [**manifest.json**](https://developer.chrome.com/extensions/manifest) **pregledač**: jednostavno prikazuje JSON-oblikovanu verziju manifesta ekstenzije.
* **Analiza otiska prsta**: Detekcija [web\_accessible\_resources](https://developer.chrome.com/extensions/manifest/web\_accessible\_resources) i automatska generacija JavaScript otiska prsta Chrome ekstenzije.
* **Analiza potencijalnog Clickjacking-a**: Detekcija HTML stranica ekstenzije sa direktivom [web\_accessible\_resources](https://developer.chrome.com/extensions/manifest/web\_accessible\_resources). Ove stranice su potencijalno ranjive na clickjacking u zavisnosti od svrhe stranica.
* **Pregled upozorenja o dozvolama**: koji prikazuje listu svih upozorenja o dozvolama Chrome-a koja će biti prikazana prilikom pokušaja korisnika da instalira ekstenziju.
* **Opasne funkcije**: prikazuje lokaciju opasnih funkcija koje bi mogle biti iskorišćene od strane napadača (npr. funkcije poput innerHTML, chrome.tabs.executeScript).
* **Ulazne tačke**: prikazuje gde ekstenzija prima korisnički/spoljni unos. Ovo je korisno za razumevanje površine ekstenzije i traženje potencijalnih tačaka za slanje zlonamerno oblikovanih podataka ekstenziji.
* I skeneri opasnih funkcija i ulaznih tačaka imaju sledeće za njihove generisane upozorenja:
* Relevantan odlomak koda i linija koja je izazvala upozorenje.
* Opis problema.
* Dugme "Prikaži fajl" za pregled celog izvornog fajla koji sadrži kod.
* Putanja upozorenog fajla.
* Potpuna URI Chrome ekstenzije upozorenog fajla.
* Vrsta fajla, kao što je skripta pozadine, Content Script, Browser Action, itd.
* Ako je ranjiva linija u JavaScript fajlu, putanje svih stranica gde je uključena kao i status ovih stranica, i [web\_accessible\_resource](https://developer.chrome.com/extensions/manifest/web\_accessible\_resources).
* **Analizator i provera zaobilaženja Politike bezbednosti sadržaja (CSP)**: Ovo će ukazati na slabosti u CSP vaše ekstenzije i takođe osvetliti bilo koje potencijalne načine zaobilaženja vaše CSP zbog belih CDN-ova, itd.
* **Poznate ranjive biblioteke**: Koristi [Retire.js](https://retirejs.github.io/retire.js/) da proveri da li se koristi poznate ranjive JavaScript biblioteke.
* Preuzmite ekstenziju i formatirane verzije.
* Preuzmite originalnu ekstenziju.
* Preuzmite prelepo formatiranu verziju ekstenzije (automatski oblikovan HTML i JavaScript).
* Automatsko keširanje rezultata skeniranja, pokretanje skeniranja ekstenzije će trajati prilično dugo prvi put kada ga pokrenete. Međutim, drugi put, pod uslovom da ekstenzija nije ažurirana, biće gotovo trenutno zbog keširanja rezultata.
* Linkabilni URL-ovi izveštaja, lako povežite nekoga sa izveštajem o ekstenziji generisanim od strane tarnish-a.
### [Neto](https://github.com/elevenpaths/neto)
Projekat Neto je Python 3 paket osmišljen za analizu i otkrivanje skrivenih funkcija browser dodataka i ekstenzija za poznate pretraživače poput Firefox-a i Chrome-a. Automatizuje proces raspakivanja zapakovanih fajlova radi izdvajanja ovih funkcija iz relevantnih resursa u ekstenziji poput `manifest.json`, lokalizacionih foldera ili JavaScript i HTML izvornih fajlova.
## Reference
* **Hvala** [**@naivenom**](https://twitter.com/naivenom) **na pomoći sa ovom metodologijom**
* [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/)
* [https://gist.github.com/LongJohnCoder/9ddf5735df3a4f2e9559665fb864eac0](https://gist.github.com/LongJohnCoder/9ddf5735df3a4f2e9559665fb864eac0)
<details>
<summary><strong>Naučite hakovanje AWS-a od nule do heroja sa</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Druge načine podrške HackTricks-u:
* Ako želite da vidite **vašu kompaniju reklamiranu na HackTricks** ili da **preuzmete HackTricks u PDF formatu** proverite [**PLANOVE ZA PRETPLATU**](https://github.com/sponsors/carlospolop)!
* Nabavite [**zvanični PEASS & HackTricks suvenir**](https://peass.creator-spring.com)
* Otkrijte [**Porodicu PEASS**](https://opensea.io/collection/the-peass-family), našu kolekciju ekskluzivnih [**NFT-ova**](https://opensea.io/collection/the-peass-family)
* **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili nas **pratite** na **Twitteru** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Podelite svoje hakovanje trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
</details>