Browser Extension Pentesting Methodology

Wsparcie dla HackTricks

Podstawowe Informacje

Rozszerzenia przeglądarki są napisane w JavaScript i ładowane przez przeglądarkę w tle. Mają swój DOM, ale mogą wchodzić w interakcje z DOM-ami innych stron. Oznacza to, że mogą naruszać poufność, integralność i dostępność (CIA) innych stron.

Główne Komponenty

Układy rozszerzeń wyglądają najlepiej, gdy są wizualizowane i składają się z trzech komponentów. Przyjrzyjmy się każdemu komponentowi dokładniej.

Skrypty Treści

Każdy skrypt treści ma bezpośredni dostęp do DOM pojedynczej strony internetowej i jest tym samym narażony na potencjalnie złośliwe dane wejściowe. Jednak skrypt treści nie zawiera żadnych uprawnień poza możliwością wysyłania wiadomości do rdzenia rozszerzenia.

Rdzeń Rozszerzenia

Rdzeń rozszerzenia zawiera większość uprawnień/dostępu rozszerzenia, ale rdzeń rozszerzenia może wchodzić w interakcje z treścią internetową tylko za pośrednictwem XMLHttpRequest i skryptów treści. Ponadto rdzeń rozszerzenia nie ma bezpośredniego dostępu do maszyny gospodarza.

Natychmiastowy Plik Binarny

Rozszerzenie pozwala na natychmiastowy plik binarny, który może uzyskać dostęp do maszyny gospodarza z pełnymi uprawnieniami użytkownika. Natychmiastowy plik binarny wchodzi w interakcje z rdzeniem rozszerzenia za pośrednictwem standardowego interfejsu programowania aplikacji Netscape Plugin (NPAPI), używanego przez Flash i inne wtyczki przeglądarki.

Granice

Aby uzyskać pełne uprawnienia użytkownika, atakujący musi przekonać rozszerzenie do przekazania złośliwych danych wejściowych ze skryptu treści do rdzenia rozszerzenia i z rdzenia rozszerzenia do natychmiastowego pliku binarnego.

Każdy komponent rozszerzenia jest oddzielony od siebie przez silne granice ochronne. Każdy komponent działa w osobnym procesie systemu operacyjnego. Skrypty treści i rdzenie rozszerzeń działają w procesach piaskownicy, niedostępnych dla większości usług systemu operacyjnego.

Co więcej, skrypty treści są oddzielone od swoich powiązanych stron internetowych przez działanie w osobnym stosie JavaScript. Skrypt treści i strona internetowa mają dostęp do tego samego podstawowego DOM, ale obie nigdy nie wymieniają wskaźników JavaScript, co zapobiega wyciekowi funkcjonalności JavaScript.

manifest.json

Rozszerzenie Chrome to po prostu folder ZIP z .crx file extension. Rdzeń rozszerzenia to plik manifest.json w katalogu głównym folderu, który określa układ, uprawnienia i inne opcje konfiguracyjne.

Przykład:

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

Skrypty zawartości są ładowane za każdym razem, gdy użytkownik nawiguję do pasującej strony, w naszym przypadku każda strona pasująca do wyrażenia https://example.com/* i niepasująca do wyrażenia regex *://*/*/business*. Wykonują się jak własne skrypty strony i mają dowolny dostęp do Modelu Obiektów Dokumentu (DOM) strony.

"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],

Aby dodać lub wykluczyć więcej adresów URL, można również użyć include_globs i exclude_globs.

To jest przykład skryptu zawartości, który doda przycisk wyjaśnienia do strony, gdy API storage zostanie użyte do pobrania wartości message z pamięci rozszerzenia.

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

Wiadomość jest wysyłana do stron rozszerzenia przez skrypt treści, gdy ten przycisk jest klikany, poprzez wykorzystanie runtime.sendMessage() API. Wynika to z ograniczenia skryptu treści w bezpośrednim dostępie do API, przy czym storage jest jednym z nielicznych wyjątków. Dla funkcjonalności wykraczających poza te wyjątki, wiadomości są wysyłane do stron rozszerzenia, z którymi skrypty treści mogą komunikować się.

W zależności od przeglądarki, możliwości skryptu treści mogą się nieco różnić. Dla przeglądarek opartych na Chromium, lista możliwości jest dostępna w dokumentacji Chrome Developers, a dla Firefox, MDN służy jako główne źródło. Warto również zauważyć, że skrypty treści mają możliwość komunikacji z skryptami w tle, co umożliwia im wykonywanie działań i przekazywanie odpowiedzi z powrotem.

Aby wyświetlić i debugować skrypty treści w Chrome, menu narzędzi dewelopera można otworzyć z Opcje > Więcej narzędzi > Narzędzia dewelopera LUB naciskając Ctrl + Shift + I.

Po wyświetleniu narzędzi dewelopera, należy kliknąć zakładkę Źródło, a następnie zakładkę Skrypty treści. Umożliwia to obserwację działających skryptów treści z różnych rozszerzeń oraz ustawienie punktów przerwania w celu śledzenia przepływu wykonania.

Wstrzyknięte skrypty treści

Zauważ, że Skrypty Treści nie są obowiązkowe, ponieważ możliwe jest również dynamiczne wstrzykiwanie skryptów oraz programowe wstrzykiwanie ich na stronach internetowych za pomocą tabs.executeScript. To w rzeczywistości zapewnia bardziej szczegółową kontrolę.

Aby programowo wstrzyknąć skrypt treści, rozszerzenie musi mieć uprawnienia hosta dla strony, do której skrypty mają być wstrzyknięte. Uprawnienia te mogą być zabezpieczone albo przez zażądanie ich w manifeście rozszerzenia, albo tymczasowo poprzez activeTab.

Przykład rozszerzenia opartego na activeTab

manifest.json
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
  • Wstrzyknij plik JS po kliknięciu:

// 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"]
});
});
  • Wstrzyknij funkcję po kliknięciu:

//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,
});
});

Przykład z uprawnieniami skryptów

// 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" });

Aby dodać lub wykluczyć więcej adresów URL, można również użyć include_globs i exclude_globs.

Skrypty zawartości run_at

Pole run_at kontroluje kiedy pliki JavaScript są wstrzykiwane do strony internetowej. Preferowana i domyślna wartość to "document_idle".

Możliwe wartości to:

  • document_idle: Kiedy tylko to możliwe

  • document_start: Po załadowaniu jakichkolwiek plików z css, ale przed skonstruowaniem jakiegokolwiek innego DOM lub uruchomieniem jakiegokolwiek innego skryptu.

  • document_end: Natychmiast po zakończeniu DOM, ale przed załadowaniem subzasobów, takich jak obrazy i ramki.

Poprzez manifest.json

{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}

Via service-worker.js

chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);

background

Wiadomości wysyłane przez skrypty treści są odbierane przez stronę w tle, która odgrywa centralną rolę w koordynowaniu komponentów rozszerzenia. Co ważne, strona w tle utrzymuje się przez cały czas trwania rozszerzenia, działając dyskretnie bez bezpośredniej interakcji użytkownika. Posiada własny Model Obiektów Dokumentu (DOM), co umożliwia złożone interakcje i zarządzanie stanem.

Kluczowe punkty:

  • Rola strony w tle: Działa jako centrum nerwowe dla rozszerzenia, zapewniając komunikację i koordynację między różnymi częściami rozszerzenia.

  • Trwałość: To zawsze obecny byt, niewidoczny dla użytkownika, ale integralny dla funkcjonalności rozszerzenia.

  • Automatyczne generowanie: Jeśli nie jest wyraźnie zdefiniowane, przeglądarka automatycznie utworzy stronę w tle. Ta automatycznie generowana strona będzie zawierać wszystkie skrypty w tle określone w manifeście rozszerzenia, zapewniając płynne działanie zadań w tle rozszerzenia.

Wygoda zapewniana przez przeglądarkę w automatycznym generowaniu strony w tle (gdy nie jest wyraźnie zadeklarowana) zapewnia, że wszystkie niezbędne skrypty w tle są zintegrowane i działają, upraszczając proces konfiguracji rozszerzenia.

Przykładowy skrypt w tle:

chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
{
if (request == "explain")
{
chrome.tabs.create({ url: "https://example.net/explanation" });
}
})

Używa runtime.onMessage API do nasłuchiwania wiadomości. Gdy otrzymana zostanie wiadomość "explain", używa tabs API do otwarcia strony w nowej karcie.

Aby debugować skrypt w tle, możesz przejść do szczegółów rozszerzenia i zbadać serwis worker, co otworzy narzędzia deweloperskie z skryptem w tle:

Strony opcji i inne

Rozszerzenia przeglądarki mogą zawierać różne rodzaje stron:

  • Strony akcji są wyświetlane w rozwijanym menu po kliknięciu na ikonę rozszerzenia.

  • Strony, które rozszerzenie załaduje w nowej karcie.

  • Strony opcji: Ta strona wyświetla się na górze rozszerzenia po kliknięciu. W poprzednim manifeście w moim przypadku mogłem uzyskać dostęp do tej strony w chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca lub klikając:

Zauważ, że te strony nie są trwałe jak strony w tle, ponieważ ładują dynamicznie treści w zależności od potrzeb. Mimo to, dzielą pewne możliwości z stroną w tle:

  • Komunikacja z skryptami treści: Podobnie jak strona w tle, te strony mogą otrzymywać wiadomości od skryptów treści, co ułatwia interakcję w ramach rozszerzenia.

  • Dostęp do specyficznych dla rozszerzenia API: Te strony mają pełny dostęp do specyficznych dla rozszerzenia API, zgodnie z uprawnieniami zdefiniowanymi dla rozszerzenia.

permissions & host_permissions

permissions i host_permissions to wpisy z manifest.json, które wskazują jakie uprawnienia ma rozszerzenie przeglądarki (przechowywanie, lokalizacja...) oraz na jakich stronach internetowych.

Ponieważ rozszerzenia przeglądarki mogą być tak uprzywilejowane, złośliwe lub skompromitowane mogłyby umożliwić atakującemu różne sposoby kradzieży wrażliwych informacji i szpiegowania użytkownika.

Sprawdź, jak te ustawienia działają i jak mogą być nadużywane w:

BrowExt - permissions & host_permissions

content_security_policy

Polityka bezpieczeństwa treści może być również zadeklarowana w manifest.json. Jeśli jest zdefiniowana, może być vulnerybilna.

Domyślne ustawienie dla stron rozszerzeń przeglądarki jest dość restrykcyjne:

script-src 'self'; object-src 'self';

Aby strona internetowa mogła uzyskać dostęp do strony rozszerzenia przeglądarki, na przykład strony .html, ta strona musi być wymieniona w polu web_accessible_resources w pliku manifest.json. Na przykład:

{
...
"web_accessible_resources": [
{
"resources": [ "images/*.png" ],
"matches": [ "https://example.com/*" ]
},
{
"resources": [ "fonts/*.woff" ],
"matches": [ "https://example.com/*" ]
}
],
...
}

Te strony są dostępne pod adresem URL takim jak:

chrome-extension://<extension-id>/message.html

W publicznych rozszerzeniach identyfikator rozszerzenia jest dostępny:

Jednakże, jeśli parametr manifest.json use_dynamic_url jest używany, ten identyfikator może być dynamiczny.

Zauważ, że nawet jeśli strona jest tutaj wymieniona, może być chroniona przed ClickJacking dzięki Polityce Bezpieczeństwa Treści. Dlatego musisz to również sprawdzić (sekcja frame-ancestors), zanim potwierdzisz, że atak ClickJacking jest możliwy.

Dopuszczenie dostępu do tych stron sprawia, że są one potencjalnie podatne na ClickJacking:

BrowExt - ClickJacking

Zezwolenie na ładowanie tych stron tylko przez rozszerzenie, a nie przez losowe adresy URL, może zapobiec atakom ClickJacking.

Zauważ, że strony z web_accessible_resources oraz inne strony rozszerzenia są również zdolne do kontaktowania się z skryptami w tle. Jeśli jedna z tych stron jest podatna na XSS, może to otworzyć większą lukę.

Ponadto, zauważ, że możesz otworzyć tylko strony wskazane w web_accessible_resources wewnątrz iframe, ale z nowej karty możliwe jest uzyskanie dostępu do dowolnej strony w rozszerzeniu, znając identyfikator rozszerzenia. Dlatego, jeśli znajdziesz XSS wykorzystujące te same parametry, może to być nadużywane, nawet jeśli strona nie jest skonfigurowana w web_accessible_resources.

externally_connectable

Zgodnie z dokumentacją, właściwość manifestu "externally_connectable" deklaruje które rozszerzenia i strony internetowe mogą łączyć się z Twoim rozszerzeniem za pomocą runtime.connect i runtime.sendMessage.

  • Jeśli klucz externally_connectable nie jest zadeklarowany w manifeście Twojego rozszerzenia lub jest zadeklarowany jako "ids": ["*"], wszystkie rozszerzenia mogą się łączyć, ale żadne strony internetowe nie mogą się łączyć.

  • Jeśli określone identyfikatory są podane, jak w "ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"], tylko te aplikacje mogą się łączyć.

  • Jeśli określone wzory są podane, te aplikacje webowe będą mogły się łączyć:

"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
  • Jeśli jest określone jako puste: "externally_connectable": {}, żadna aplikacja ani strona internetowa nie będą mogły się połączyć.

Im mniej rozszerzeń i adresów URL wskazanych tutaj, tym mniejsza powierzchnia ataku.

Jeśli strona internetowa wrażliwa na XSS lub przejęcie jest wskazana w externally_connectable, atakujący będzie mógł wysyłać wiadomości bezpośrednio do skryptu w tle, całkowicie omijając skrypt treści i jego CSP.

Dlatego jest to bardzo potężne obejście.

Co więcej, jeśli klient zainstaluje złośliwe rozszerzenie, nawet jeśli nie jest dozwolone do komunikacji z wrażliwym rozszerzeniem, może wstrzyknąć dane XSS w dozwolonej stronie internetowej lub nadużyć WebRequest lub DeclarativeNetRequest API, aby manipulować żądaniami na docelowej domenie, zmieniając żądanie strony dla pliku JavaScript. (Zauważ, że CSP na docelowej stronie może zapobiec tym atakom). Ten pomysł pochodzi z tego opisu.

Podsumowanie komunikacji

Rozszerzenie <--> WebApp

Aby komunikować się między skryptem treści a stroną internetową, zazwyczaj używane są wiadomości post. Dlatego w aplikacji internetowej zazwyczaj znajdziesz wywołania funkcji window.postMessage oraz w skrypcie treści nasłuchiwacze, takie jak window.addEventListener. Należy jednak pamiętać, że rozszerzenie może również komunikować się z aplikacją internetową, wysyłając wiadomość Post (a zatem strona powinna się tego spodziewać) lub po prostu sprawić, by strona załadowała nowy skrypt.

Wewnątrz rozszerzenia

Zazwyczaj funkcja chrome.runtime.sendMessage jest używana do wysyłania wiadomości wewnątrz rozszerzenia (zazwyczaj obsługiwana przez skrypt background), a aby ją odebrać i obsłużyć, deklarowany jest nasłuchiwacz wywołujący chrome.runtime.onMessage.addListener.

Możliwe jest również użycie chrome.runtime.connect() do nawiązania trwałego połączenia zamiast wysyłania pojedynczych wiadomości, można go użyć do wysyłania i odbierania wiadomości, jak w poniższym przykładzie:

chrome.runtime.connect() przykład

```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>

Możliwe jest również wysyłanie wiadomości z skryptu w tle do skryptu treści znajdującego się w określonej karcie, wywołując **`chrome.tabs.sendMessage`**, gdzie będziesz musiał wskazać **ID karty**, do której chcesz wysłać wiadomość.

### Z dozwolonego `externally_connectable` do rozszerzenia

**Aplikacje internetowe i zewnętrzne rozszerzenia przeglądarki dozwolone** w konfiguracji `externally_connectable` mogą wysyłać żądania za pomocą:
```javascript
chrome.runtime.sendMessage(extensionId, ...

Gdzie to konieczne, aby wspomnieć o identyfikatorze rozszerzenia.

Komunikacja Web ↔︎ Skryptów Treści

Środowiska, w których działają skrypty treści oraz gdzie istnieją strony hosta, są oddzielone od siebie, zapewniając izolację. Pomimo tej izolacji, obie strony mają możliwość interakcji z Model Obiektów Dokumentu (DOM) strony, wspólnym zasobem. Aby strona hosta mogła nawiązać komunikację z skryptem treści, lub pośrednio z rozszerzeniem przez skrypt treści, konieczne jest wykorzystanie DOM, który jest dostępny dla obu stron jako kanał komunikacyjny.

Wiadomości Post

content-script.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);
example.js
document.getElementById("theButton").addEventListener("click", () => {
window.postMessage(
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);

Bezpieczna komunikacja Post Message powinna sprawdzać autentyczność otrzymanej wiadomości, co można zrobić, sprawdzając:

  • event.isTrusted: To jest True tylko wtedy, gdy zdarzenie zostało wywołane przez akcję użytkownika

  • Skrypt treści może oczekiwać wiadomości tylko wtedy, gdy użytkownik wykona jakąś akcję

  • domena źródłowa: może oczekiwać wiadomości tylko z dozwolonej listy domen.

  • Jeśli używana jest wyrażenie regularne, bądź bardzo ostrożny

  • Źródło: received_message.source !== window może być użyte do sprawdzenia, czy wiadomość była z tej samej okna, w którym skrypt treści nasłuchuje.

Poprzednie kontrole, nawet jeśli są przeprowadzane, mogą być podatne, więc sprawdź na następującej stronie potencjalne obejścia Post Message:

Iframe

Innym możliwym sposobem komunikacji mogą być adresy URL Iframe, przykład można znaleźć w:

DOM

To nie jest "dokładnie" sposób komunikacji, ale sieć i skrypt treści będą miały dostęp do DOM sieci. Więc, jeśli skrypt treści odczytuje jakieś informacje z niego, ufając DOM sieci, sieć mogłaby zmodyfikować te dane (ponieważ sieć nie powinna być ufana, lub ponieważ sieć jest podatna na XSS) i skompromentować skrypt treści.

Możesz również znaleźć przykład XSS opartego na DOM, aby skompromitować rozszerzenie przeglądarki w:

Komunikacja Skryptu Treści ↔︎ Skryptu Tła

Skrypt treści może używać funkcji runtime.sendMessage() lub tabs.sendMessage() do wysyłania jednorazowej wiadomości w formacie JSON.

Aby obsłużyć odpowiedź, użyj zwróconego Promise. Chociaż, dla zachowania zgodności wstecznej, nadal możesz przekazać callback jako ostatni argument.

Wysyłanie żądania z skryptu treści wygląda tak:

(async () => {
const response = await chrome.runtime.sendMessage({greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();

Wysyłanie żądania z rozszerzenia (zwykle skryptu w tle). Przykład, jak wysłać wiadomość do skryptu treści w wybranej karcie:

// 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 odbiorze musisz ustawić runtime.onMessage nasłuchiwacz zdarzeń, aby obsłużyć wiadomość. Wygląda to tak samo z poziomu skryptu treści lub strony rozszerzenia.

// 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"});
}
);

W wyróżnionym przykładzie, sendResponse() został wykonany w sposób synchroniczny. Aby zmodyfikować obsługę zdarzenia onMessage do asynchronicznego wykonania sendResponse(), konieczne jest dodanie return true;.

Ważnym rozważaniem jest to, że w scenariuszach, w których wiele stron jest ustawionych do odbierania zdarzeń onMessage, pierwsza strona, która wykona sendResponse() dla konkretnego zdarzenia, będzie jedyną, która skutecznie dostarczy odpowiedź. Jakiekolwiek kolejne odpowiedzi na to samo zdarzenie nie będą brane pod uwagę.

Podczas tworzenia nowych rozszerzeń preferencje powinny być skierowane ku obietnicom zamiast do wywołań zwrotnych. W odniesieniu do użycia wywołań zwrotnych, funkcja sendResponse() jest uznawana za ważną tylko wtedy, gdy jest wykonywana bezpośrednio w kontekście synchronicznym lub jeśli obsługa zdarzenia wskazuje na operację asynchroniczną, zwracając true. Jeśli żaden z handlerów nie zwróci true lub jeśli funkcja sendResponse() zostanie usunięta z pamięci (zbierana przez garbage collector), wywołanie zwrotne związane z funkcją sendMessage() zostanie wywołane domyślnie.

Wrażliwe informacje w pamięci/kodzie/clipboard

Jeśli Rozszerzenie Przeglądarki przechowuje wrażliwe informacje w swojej pamięci, mogą one być zrzucane (szczególnie na maszynach z systemem Windows) i przeszukiwane w poszukiwaniu tych informacji.

Dlatego pamięć Rozszerzenia Przeglądarki nie powinna być uważana za bezpieczną i wrażliwe informacje takie jak dane logowania czy frazy mnemoniczne nie powinny być przechowywane.

Oczywiście, nie umieszczaj wrażliwych informacji w kodzie, ponieważ będą one publiczne.

Aby zrzucić pamięć z przeglądarki, możesz zrzucić pamięć procesu lub przejść do ustawień rozszerzenia przeglądarki, klikając Inspect pop-up -> W sekcji Memory -> Take a snapshot i CTRL+F aby przeszukać zrzut w poszukiwaniu wrażliwych informacji.

Ponadto, wysoce wrażliwe informacje, takie jak klucze mnemoniczne czy hasła, nie powinny mieć możliwości kopiowania do schowka (lub przynajmniej powinny być usuwane ze schowka w ciągu kilku sekund), ponieważ wtedy procesy monitorujące schowek będą mogły je uzyskać.

Ładowanie rozszerzenia w przeglądarce

  1. Pobierz Rozszerzenie Przeglądarki i rozpakuj

  2. Przejdź do chrome://extensions/ i włącz Tryb dewelopera

  3. Kliknij przycisk Załaduj rozpakowane

W Firefoxie przejdź do about:debugging#/runtime/this-firefox i kliknij przycisk Załaduj tymczasowy dodatek.

Uzyskiwanie kodu źródłowego ze sklepu

Kod źródłowy rozszerzenia Chrome można uzyskać na różne sposoby. Poniżej znajdują się szczegółowe wyjaśnienia i instrukcje dla każdej opcji.

Pobierz rozszerzenie jako ZIP za pomocą wiersza poleceń

Kod źródłowy rozszerzenia Chrome można pobrać jako plik ZIP za pomocą wiersza poleceń. Wymaga to użycia curl do pobrania pliku ZIP z określonego adresu URL, a następnie wyodrębnienia zawartości pliku ZIP do katalogu. Oto kroki:

  1. Zastąp "extension_id" rzeczywistym ID rozszerzenia.

  2. Wykonaj następujące polecenia:

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"

Użyj strony CRX Viewer

https://robwu.nl/crxviewer/

Użyj rozszerzenia CRX Viewer

Inną wygodną metodą jest użycie Chrome Extension Source Viewer, który jest projektem open-source. Można go zainstalować z Chrome Web Store. Kod źródłowy widoku jest dostępny w jego repozytorium GitHub.

Wyświetl źródło lokalnie zainstalowanego rozszerzenia

Rozszerzenia Chrome zainstalowane lokalnie można również sprawdzić. Oto jak:

  1. Uzyskaj dostęp do lokalnego katalogu profilu Chrome, odwiedzając chrome://version/ i lokalizując pole "Profile Path".

  2. Przejdź do podfolderu Extensions/ w katalogu profilu.

  3. Ten folder zawiera wszystkie zainstalowane rozszerzenia, zazwyczaj z ich kodem źródłowym w czytelnym formacie.

Aby zidentyfikować rozszerzenia, możesz powiązać ich identyfikatory z nazwami:

  • Włącz tryb dewelopera na stronie about:extensions, aby zobaczyć identyfikatory każdego rozszerzenia.

  • W folderze każdego rozszerzenia plik manifest.json zawiera czytelne pole name, co pomaga w identyfikacji rozszerzenia.

Użyj archiwizera plików lub dekompresora

Przejdź do Chrome Web Store i pobierz rozszerzenie. Plik będzie miał rozszerzenie .crx. Zmień rozszerzenie pliku z .crx na .zip. Użyj dowolnego archiwizera plików (takiego jak WinRAR, 7-Zip itp.), aby wyodrębnić zawartość pliku ZIP.

Użyj trybu dewelopera w Chrome

Otwórz Chrome i przejdź do chrome://extensions/. Włącz "Tryb dewelopera" w prawym górnym rogu. Kliknij "Załaduj rozpakowane rozszerzenie...". Przejdź do katalogu swojego rozszerzenia. To nie pobiera kodu źródłowego, ale jest przydatne do przeglądania i modyfikowania kodu już pobranego lub opracowanego rozszerzenia.

Lista kontrolna audytu bezpieczeństwa

Chociaż rozszerzenia przeglądarki mają ograniczoną powierzchnię ataku, niektóre z nich mogą zawierać luki lub potencjalne poprawki wzmocnienia. Oto najczęstsze z nich:

Narzędzia

  • Pobiera dowolne rozszerzenie Chrome z podanego linku do Chrome Webstore.

  • manifest.json widok: po prostu wyświetla wersję JSON w formacie prettified manifestu rozszerzenia.

  • Analiza odcisków palców: Wykrywanie web_accessible_resources i automatyczne generowanie JavaScript do odcisków palców rozszerzenia Chrome.

  • Potencjalna analiza Clickjacking: Wykrywanie stron HTML rozszerzenia z ustawioną dyrektywą web_accessible_resources. Mogą być potencjalnie podatne na clickjacking w zależności od celu stron.

  • Widok ostrzeżeń o uprawnieniach: który pokazuje listę wszystkich ostrzeżeń o uprawnieniach Chrome, które będą wyświetlane, gdy użytkownik spróbuje zainstalować rozszerzenie.

  • Niebezpieczna funkcja: pokazuje lokalizację niebezpiecznych funkcji, które mogą być potencjalnie wykorzystywane przez atakującego (np. funkcje takie jak innerHTML, chrome.tabs.executeScript).

  • Punkty wejścia: pokazuje, gdzie rozszerzenie przyjmuje dane wejściowe od użytkownika/zewnętrzne. To jest przydatne do zrozumienia powierzchni rozszerzenia i szukania potencjalnych punktów do wysyłania złośliwie skonstruowanych danych do rozszerzenia.

  • Zarówno skanery Niebezpiecznych Funkcji, jak i Punktów Wejścia mają następujące dla swoich wygenerowanych alertów:

  • Odpowiedni fragment kodu i linia, która spowodowała alert.

  • Opis problemu.

  • Przycisk "Zobacz plik", aby zobaczyć pełny plik źródłowy zawierający kod.

  • Ścieżka alertowanego pliku.

  • Pełny URI rozszerzenia Chrome alertowanego pliku.

  • Typ pliku, taki jak skrypt strony w tle, skrypt treści, akcja przeglądarki itp.

  • Jeśli podatna linia znajduje się w pliku JavaScript, ścieżki wszystkich stron, na których jest zawarta, a także typ tych stron oraz status web_accessible_resource.

  • Analizator polityki bezpieczeństwa treści (CSP) i sprawdzacz obejść: Wskaże słabości w CSP twojego rozszerzenia i również oświetli wszelkie potencjalne sposoby obejścia twojego CSP z powodu białych list CDN itp.

  • Znane podatne biblioteki: Używa Retire.js, aby sprawdzić, czy używane są znane podatne biblioteki JavaScript.

  • Pobierz rozszerzenie i sformatowane wersje.

  • Pobierz oryginalne rozszerzenie.

  • Pobierz wersję rozszerzenia w formacie beautified (automatycznie sformatowany HTML i JavaScript).

  • Automatyczne buforowanie wyników skanowania, uruchomienie skanowania rozszerzenia zajmie sporo czasu przy pierwszym uruchomieniu. Jednak przy drugim uruchomieniu, zakładając, że rozszerzenie nie zostało zaktualizowane, będzie prawie natychmiastowe dzięki buforowanym wynikom.

  • Linkowalne adresy URL raportów, łatwo linkuj kogoś do raportu rozszerzenia wygenerowanego przez tarnish.

Projekt Neto to pakiet Pythona 3 stworzony do analizy i odkrywania ukrytych funkcji wtyczek i rozszerzeń przeglądarek dla znanych przeglądarek, takich jak Firefox i Chrome. Automatyzuje proces rozpakowywania spakowanych plików, aby wyodrębnić te funkcje z odpowiednich zasobów w rozszerzeniu, takich jak manifest.json, foldery lokalizacyjne lub pliki źródłowe JavaScript i HTML.

Odniesienia

Last updated