.. | ||
browext-clickjacking.md | ||
browext-permissions-and-host_permissions.md | ||
browext-xss-example.md | ||
README.md |
Metodologia testowania penetracyjnego rozszerzeń przeglądarki
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź SUBSCRIPTION PLANS!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.
Podstawowe informacje
Rozszerzenia przeglądarki są napisane w języku JavaScript i są ładowane przez przeglądarkę w tle. Posiadają swój DOM, ale mogą współdziałać z DOM innego serwisu. Oznacza to, że mogą naruszać poufność, integralność i dostępność (CIA) innych serwisów.
Główne komponenty
Wygląd rozszerzenia prezentuje się najlepiej, gdy jest wizualizowany i składa się z trzech komponentów. Przyjrzyjmy się każdemu z nich dokładniej.
Skrypty treści
Każdy skrypt treści ma bezpośredni dostęp do DOM jednej strony internetowej i jest tym samym narażony na potencjalnie złośliwe dane wejściowe. Jednak skrypt treści nie posiada żadnych uprawnień poza możliwością wysyłania wiadomości do rdzenia rozszerzenia.
Rdzeń rozszerzenia
Rdzeń rozszerzenia zawiera większość uprawnień/dostępów rozszerzenia, ale rdzeń rozszerzenia może jedynie współdziałać z treścią internetową za pomocą XMLHttpRequest i skryptów treści. Ponadto, rdzeń rozszerzenia nie ma bezpośredniego dostępu do maszyny hosta.
Binarny plik natywny
Rozszerzenie umożliwia użycie binarnego pliku natywnego, który może uzyskać dostęp do maszyny hosta z pełnymi uprawnieniami użytkownika. Binarny plik natywny współdziała z rdzeniem rozszerzenia za pomocą standardowego interfejsu programowania aplikacji Netscape Plugin (NPAPI), używanego przez Flash i inne wtyczki przeglądarkowe.
Granice
{% hint style="danger" %} Aby uzyskać pełne uprawnienia użytkownika, atakujący musi przekonać rozszerzenie do przekazywania złośliwych danych wejściowych ze skryptu treści do rdzenia rozszerzenia oraz z rdzenia rozszerzenia do binarnego pliku natywnego. {% endhint %}
Każdy komponent rozszerzenia jest odseparowany od siebie za pomocą silnych granic ochronnych. Każdy komponent działa w oddzielnym procesie systemu operacyjnego. Skrypty treści i rdzenie rozszerzeń działają w procesach piaskownicy, niedostępnych dla większości usług systemu operacyjnego.
Ponadto, skrypty treści oddzielone są od powiązanych z nimi stron internetowych przez działanie w oddzielnej stercie JavaScript. Skrypt treści i strona internetowa mają dostęp do tego samego DOM, ale nigdy nie wymieniają wskaźników JavaScript, co zapobiega wyciekom funkcjonalności JavaScript.
manifest.json
Rozszerzenie Chrome to po prostu folder ZIP z rozszerzeniem .crx. Głównym komponentem rozszerzenia jest plik manifest.json
znajdujący się w głównym katalogu 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 przechodzi do pasującej strony, w naszym przypadku do dowolnej strony pasującej do wyrażenia https://example.com/*
i nie pasującej do wyrażenia regularnego *://*/*/business*
. Wykonują się jak własne skrypty strony i mają dowolny dostęp do Modelu Obiektowego Dokumentu (DOM) strony.
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
Aby uwzględnić lub wykluczyć więcej adresów URL, można również użyć include_globs
i exclude_globs
.
Oto przykładowy skrypt zawartości, który doda przycisk "Wyjaśnij" na stronie, korzystając z interfejsu API przechowywania do pobrania wartości message
z pamięci podręcznej 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 zawartości, gdy ten przycisk jest kliknięty, poprzez wykorzystanie API runtime.sendMessage(). Wynika to z ograniczeń skryptu zawartości w bezpośrednim dostępie do interfejsów API, z wyjątkiem storage
, który jest jednym z niewielu wyjątków. Dla funkcji poza tymi wyjątkami, wiadomości są wysyłane do stron rozszerzenia, z którymi skrypty zawartości mogą się komunikować.
{% hint style="warning" %}
W zależności od przeglądarki, możliwości skryptu zawartości mogą się nieznacznie różnić. Dla przeglądarek opartych na Chromium, lista możliwości jest dostępna w dokumentacji Chrome Developers, a dla przeglądarki Firefox, MDN jest głównym źródłem informacji.
Warto również zauważyć, że skrypty zawartości mają możliwość komunikacji z skryptami tła, co pozwala im wykonywać działania i przekazywać odpowiedzi.
{% endhint %}
Aby wyświetlić i debugować skrypty zawartości w Chrome, można uzyskać dostęp do menu narzędzi deweloperskich Chrome, przechodząc do Opcje > Więcej narzędzi > Narzędzia dla deweloperów LUB naciskając Ctrl + Shift + I.
Po wyświetleniu narzędzi deweloperskich należy kliknąć zakładkę Source, a następnie zakładkę Content Scripts. Pozwala to na obserwację działających skryptów zawartości z różnych rozszerzeń oraz ustawianie punktów przerwania w celu śledzenia przepływu wykonania.
Wstrzykiwane skrypty zawartości
{% hint style="success" %}
Należy zauważyć, że skrypty zawartości nie są obowiązkowe, ponieważ możliwe jest również dynamiczne wstrzykiwanie skryptów i programowe wstrzykiwanie ich na strony internetowe za pomocą tabs.executeScript
. Zapewnia to większą kontrolę szczegółową.
{% endhint %}
Aby programowo wstrzyknąć skrypt zawartości, rozszerzenie musi mieć uprawnienia hosta dla strony, do której mają być wstrzykiwane skrypty. Uprawnienia te można zabezpieczyć poprzez żądanie ich w manifeście rozszerzenia lub tymczasowo za pomocą activeTab.
Przykład rozszerzenia opartego na activeTab
{% code title="manifest.json" %}
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
{% endcode %}
- Wstrzyknięcie pliku 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"]
});
});
- Wstrzyknięcie funkcji 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 skryptowymi
In some cases, browser extensions may have scripting permissions that allow them to execute arbitrary code on web pages. This can be a potential security risk as malicious extensions can abuse these permissions to perform unauthorized actions.
W niektórych przypadkach rozszerzenia przeglądarki mogą mieć uprawnienia skryptowe, które pozwalają im wykonywać dowolny kod na stronach internetowych. Może to stanowić potencjalne zagrożenie dla bezpieczeństwa, ponieważ złośliwe rozszerzenia mogą wykorzystać te uprawnienia do wykonania nieautoryzowanych działań.
To identify if a browser extension has scripting permissions, you can inspect its manifest file. Look for the "permissions" field and check if it includes the "scripting" permission.
Aby sprawdzić, czy rozszerzenie przeglądarki ma uprawnienia skryptowe, można sprawdzić plik manifestu. Szukaj pola "permissions" i sprawdź, czy zawiera uprawnienie "scripting".
If the extension has scripting permissions, you can analyze its source code to understand how it interacts with web pages. Look for functions or event listeners that are executed on specific events, such as page load or button clicks.
Jeśli rozszerzenie ma uprawnienia skryptowe, można przeanalizować jego kod źródłowy, aby zrozumieć, jak współdziała z stronami internetowymi. Szukaj funkcji lub nasłuchiwaczy zdarzeń, które są wykonywane w określonych momentach, takich jak załadowanie strony lub kliknięcie przycisku.
Once you have identified the code responsible for executing on web pages, you can analyze its functionality and look for any potential security vulnerabilities. Pay attention to how the extension interacts with user input and external resources.
Po zidentyfikowaniu kodu odpowiedzialnego za wykonanie na stronach internetowych, można przeanalizować jego funkcjonalność i szukać potencjalnych podatności bezpieczeństwa. Zwróć uwagę na to, w jaki sposób rozszerzenie współdziała z danymi wprowadzanymi przez użytkownika i zewnętrznymi zasobami.
It is also important to review the permissions requested by the extension. If the extension requests excessive permissions that are not necessary for its intended functionality, it may indicate a potential security risk.
Ważne jest również przejrzenie żądanych uprawnień przez rozszerzenie. Jeśli rozszerzenie żąda nadmiernych uprawnień, które nie są niezbędne do jego zamierzonej funkcjonalności, może to wskazywać na potencjalne zagrożenie dla bezpieczeństwa.
Regularly updating and reviewing the browser extensions installed on your system is crucial to ensure that you are not exposed to any security risks. Remove any unnecessary or suspicious extensions and only install those from trusted sources.
Regularne aktualizowanie i przeglądanie zainstalowanych rozszerzeń przeglądarki na Twoim systemie jest kluczowe, aby upewnić się, że nie jesteś narażony na żadne zagrożenia dla bezpieczeństwa. Usuń wszelkie niepotrzebne lub podejrzane rozszerzenia i instaluj tylko te pochodzące z zaufanych źródeł.
// 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 uwzględnić 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
: Kiedykolwiek to możliwedocument_start
: Po plikachcss
, ale przed konstrukcją jakiegokolwiek innego DOM-u lub uruchomieniem jakiegokolwiek innego skryptu.document_end
: Bezpośrednio po zakończeniu konstrukcji DOM-u, ale przed załadowaniem zasobów podrzędnych, takich jak obrazy i ramki.
Przez manifest.json
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
Poprzez service-worker.js
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);
tło
Wiadomości wysyłane przez skrypty zawartości są odbierane przez stronę tła, która pełni centralną rolę w koordynacji komponentów rozszerzenia. Strona tła działa niezauważalnie i bezpośredniej interakcji użytkownika, a także posiada własny Model Obiektowy Dokumentu (DOM), umożliwiający kompleksowe interakcje i zarządzanie stanem.
Kluczowe punkty:
- Rola strony tła: Pełni funkcję centrum nerwowego rozszerzenia, zapewniając komunikację i koordynację między różnymi częściami rozszerzenia.
- Trwałość: Jest obecna przez cały czas istnienia rozszerzenia, niewidoczna dla użytkownika, ale integralna dla funkcjonalności rozszerzenia.
- Automatyczne generowanie: Jeśli nie jest jawnie zdefiniowana, przeglądarka automatycznie utworzy stronę tła. Ta automatycznie wygenerowana strona będzie zawierać wszystkie skrypty tła określone w manifeście rozszerzenia, zapewniając bezproblemowe działanie zadań tła rozszerzenia.
{% hint style="success" %} Wygodne automatyczne generowanie strony tła przez przeglądarkę (jeśli nie jest jawnie zadeklarowane) zapewnia, że wszystkie niezbędne skrypty tła są zintegrowane i działające, usprawniając proces konfiguracji rozszerzenia. {% endhint %}
Przykładowy skrypt tła:
chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
{
if (request == "explain")
{
chrome.tabs.create({ url: "https://example.net/explanation" });
}
})
Wykorzystuje API runtime.onMessage do nasłuchiwania wiadomości. Gdy otrzyma wiadomość "explain", używa API tabs do otwarcia strony w nowej karcie.
Aby debugować skrypt tła, możesz przejść do szczegółów rozszerzenia i sprawdzić serwis workera, co spowoduje otwarcie narzędzi developerskich z skryptem tła:
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 pod adresem
chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca
lub klikając:
Należy zauważyć, że te strony nie są trwałe, tak jak strony tła, ponieważ dynamicznie ładowane są tylko w razie potrzeby. Mimo to, mają pewne możliwości wspólne z stroną tła:
- Komunikacja z skryptami zawartości: Podobnie jak strona tła, te strony mogą otrzymywać wiadomości od skryptów zawartości, ułatwiając interakcję w obrębie 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
i host_permissions
permissions
i host_permissions
to wpisy w pliku manifest.json
, które wskazują, jakie uprawnienia ma rozszerzenie przeglądarki (np. dostęp do pamięci, lokalizacji...) i na jakich stronach internetowych.
Ponieważ rozszerzenia przeglądarki mogą być tak uprzywilejowane, złośliwe lub skompromitowane rozszerzenie może umożliwić atakującemu różne sposoby kradzieży poufnych informacji i szpiegowania użytkownika.
Sprawdź, jak działają te ustawienia i jak mogą być nadużywane w:
{% content-ref url="browext-permissions-and-host_permissions.md" %} browext-permissions-and-host_permissions.md {% endcontent-ref %}
content_security_policy
Polityka bezpieczeństwa zawartości może być również zadeklarowana w pliku manifest.json
. Jeśli jest zdefiniowana, może być podatna.
Domyślne ustawienie dla stron rozszerzenia przeglądarki jest dość restrykcyjne:
script-src 'self'; object-src 'self';
Aby uzyskać więcej informacji na temat CSP i potencjalnych sposobów obejścia, sprawdź:
{% content-ref url="../content-security-policy-csp-bypass/" %} content-security-policy-csp-bypass {% endcontent-ref %}
web_accessible_resources
Aby strona internetowa mogła uzyskać dostęp do strony rozszerzenia przeglądarki, na przykład do pliku .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 używany jest parametr use_dynamic_url
w pliku manifest.json
, to ten identyfikator może być dynamiczny.
Dostęp do tych stron może sprawić, że są one potencjalnie podatne na ataki ClickJacking:
{% content-ref url="browext-clickjacking.md" %} browext-clickjacking.md {% endcontent-ref %}
{% hint style="success" %} Ograniczenie ładowania tych stron tylko przez rozszerzenie, a nie przez losowe adresy URL, może zapobiec atakom ClickJacking. {% endhint %}
externally_connectable
Zgodnie z dokumentacją, właściwość manifestu "externally_connectable"
deklaruje, które rozszerzenia i strony internetowe mogą się połączyć z Twoim rozszerzeniem za pomocą runtime.connect i runtime.sendMessage.
- Jeśli klucz
externally_connectable
nie jest zadeklarowany w manifestie Twojego rozszerzenia lub jest zadeklarowany jako"ids": ["*"]
, wszystkie rozszerzenia mogą się połączyć, ale żadne strony internetowe nie mogą. - Jeśli są określone konkretne identyfikatory, jak w
"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
, tylko te aplikacje mogą się połączyć. - Jeśli są określone dopasowania, te aplikacje internetowe będą mogły się połączyć:
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
- Jeśli jest określone jako puste:
"externally_connectable": {}
, żadna aplikacja ani strona internetowa nie będzie mogła się połączyć.
Im mniej rozszerzeń i adresów URL tutaj wskazanych, tym mniejsza powierzchnia ataku.
{% hint style="danger" %}
Jeśli na stronie internetowej podatnej na XSS lub przejęcie jest wskazane externally_connectable
, atakujący będzie mógł wysyłać wiadomości bezpośrednio do skryptu w tle, całkowicie omijając Skrypt Zawartości i jego CSP.
Jest to więc bardzo potężne obejście. {% endhint %}
Komunikacja między stroną internetową ↔︎ Skryptem Zawartości
Środowiska, w których działają skrypty zawartości i w których istnieją strony hosta, są od siebie oddzielone, zapewniając izolację. Pomimo tej izolacji, oba mają możliwość interakcji z Model Obiektowy Dokumentu (DOM) strony, który jest wspólnym zasobem. Aby strona hosta mogła komunikować się ze skryptem zawartości, lub pośrednio z rozszerzeniem poprzez skrypt zawartości, konieczne jest wykorzystanie DOM dostępnego dla obu stron jako kanału komunikacji.
Wiadomości Post
{% code title="content-script.js" %}
var port = chrome.runtime.connect();
window.addEventListener("message", (event) => {
// We only accept messages from ourselves
if (event.source !== window) {
return;
}
if (event.data.type && (event.data.type === "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
}
}, false);
{% code title="example.js" %}
document.getElementById("theButton").addEventListener("click", () => {
window.postMessage(
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);
{% endcode %}
Bezpieczna komunikacja Post Message powinna sprawdzać autentyczność otrzymanej wiadomości, można to zrobić sprawdzając:
event.isTrusted
: Jest to prawdziwe tylko wtedy, gdy zdarzenie zostało wywołane przez działanie użytkownika.- Skrypt zawartości może oczekiwać wiadomości tylko wtedy, gdy użytkownik wykonuje jakieś działanie.
- Domena pochodzenia: może oczekiwać wiadomości tylko z listy zaufanych domen.
- Jeśli używane jest wyrażenie regularne, należy być bardzo ostrożnym.
- Źródło:
received_message.source !== window
można użyć do sprawdzenia, czy wiadomość pochodzi z tego samego okna, w którym nasłuchuje skrypt zawartości.
Wcześniejsze sprawdzenia, nawet jeśli są wykonywane, mogą być podatne na ataki, dlatego sprawdź na następnej stronie potencjalne sposoby obejścia Post Message:
{% content-ref url="../postmessage-vulnerabilities/" %} postmessage-vulnerabilities {% endcontent-ref %}
Iframe
Inną możliwą metodą komunikacji może być za pomocą adresów URL Iframe, przykład można znaleźć tutaj:
{% content-ref url="browext-xss-example.md" %} browext-xss-example.md {% endcontent-ref %}
DOM
To nie jest "dokładnie" sposób komunikacji, ale strona internetowa i skrypt zawartości będą miały dostęp do DOM strony internetowej. Jeśli skrypt zawartości odczytuje pewne informacje z niego, ufając DOM strony internetowej, strona internetowa może modyfikować te dane (ponieważ strona internetowa nie powinna być ufać, lub ponieważ strona internetowa jest podatna na XSS) i naruszać bezpieczeństwo skryptu zawartości.
Przykład DOM based XSS do naruszenia rozszerzenia przeglądarki można również znaleźć tutaj:
{% content-ref url="browext-xss-example.md" %} browext-xss-example.md {% endcontent-ref %}
Wrażliwe informacje w pamięci/kodzie
Jeśli rozszerzenie przeglądarki przechowuje wrażliwe informacje w pamięci, mogą one zostać wydobyte (szczególnie na maszynach z systemem Windows) i przeszukane w celu znalezienia tych informacji.
Dlatego pamięć rozszerzenia przeglądarki nie powinna być uważana za bezpieczną, a wrażliwe informacje, takie jak poświadczenia lub frazy mnemotechniczne, nie powinny być przechowywane.
Oczywiście nie umieszczaj wrażliwych informacji w kodzie, ponieważ będą one publiczne.
Komunikacja między skryptem zawartości a skryptem tła
Skrypt zawartoś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. Jednak dla zachowania kompatybilności wstecznej, nadal można przekazać callback jako ostatni argument.
Wysłanie żądania z skryptu zawartoś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 (zazwyczaj z skryptu tła) Skrypt zawartości może korzystać z funkcji, z tym że musisz określić, do którego zakładki ma zostać wysłane. Przykład wysłania wiadomości do skryptu zawartości w wybranej zakładce:
// 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 stronie odbiorczej musisz skonfigurować runtime.onMessage słuchacz zdarzeń, aby obsłużyć wiadomość. Wygląda to tak samo zarówno w skrypcie treści, jak i na stronie 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 podanym przykładzie funkcja sendResponse()
została wykonana synchronicznie. Aby zmodyfikować obsługę zdarzenia onMessage
w celu asynchronicznego wykonania funkcji sendResponse()
, konieczne jest dodanie instrukcji return true;
.
Ważnym czynnikiem jest to, że w przypadku, gdy wiele stron ma odbierać zdarzenia onMessage
, pierwsza strona, która wykonuje funkcję sendResponse()
dla danego zdarzenia, będzie jedyną, która skutecznie dostarczy odpowiedź. Wszelkie kolejne odpowiedzi na to samo zdarzenie nie będą brane pod uwagę.
Tworząc nowe rozszerzenia, należy preferować użycie obietnic zamiast wywołań zwrotnych. Jeśli chodzi o użycie wywołań zwrotnych, funkcja sendResponse()
jest uważana za ważną tylko wtedy, gdy jest wykonywana bezpośrednio w kontekście synchronicznym lub gdy obsługa zdarzenia wskazuje na operację asynchroniczną przez zwrócenie wartości true
. Jeśli żadna z obsług nie zwraca wartości true
lub jeśli funkcja sendResponse()
zostanie usunięta z pamięci (zebrana przez garbage collector), wywołanie zwrotne powiązane z funkcją sendMessage()
zostanie domyślnie uruchomione.
Ładowanie rozszerzenia w przeglądarce
- Pobierz rozszerzenie przeglądarki i rozpakuj je
- Przejdź do
chrome://extensions/
i włącz trybDeveloper Mode
- Kliknij przycisk
Load unpacked
W Firefoxie przejdź do about:debugging#/runtime/this-firefox
i kliknij przycisk Load Temporary Add-on
.
Pobieranie kodu źródłowego z sklepu
Kod źródłowy rozszerzenia Chrome można uzyskać za pomocą różnych metod. Poniżej znajdują się szczegółowe wyjaśnienia i instrukcje dla każdej opcji.
Pobieranie rozszerzenia jako pliku 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 polecenia curl
, aby pobrać plik ZIP z określonego adresu URL, a następnie rozpakowania zawartości pliku ZIP do katalogu. Oto kroki do wykonania:
- Zastąp
"extension_id"
rzeczywistym identyfikatorem rozszerzenia. - 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 internetowej CRX Viewer
Użyj rozszerzenia CRX Viewer
Inną wygodną metodą jest użycie rozszerzenia Chrome Extension Source Viewer, które jest projektem open-source. Można je zainstalować ze Sklepu Chrome Web Store. Kod źródłowy przeglądarki jest dostępny w repozytorium GitHub.
Wyświetlanie źródła lokalnie zainstalowanego rozszerzenia
Lokalnie zainstalowane rozszerzenia Chrome można również sprawdzić. Oto jak to zrobić:
- Otwórz folder lokalnego profilu Chrome, odwiedzając
chrome://version/
i znajdując pole "Profile Path". - Przejdź do podfolderu
Extensions/
w folderze profilu. - Ten folder zawiera wszystkie zainstalowane rozszerzenia, zazwyczaj z kodem źródłowym w czytelnej formie.
Aby zidentyfikować rozszerzenia, można przyporządkować ich identyfikatory do nazw:
- Włącz tryb dewelopera na stronie
about:extensions
, aby zobaczyć identyfikatory każdego rozszerzenia. - W folderze każdego rozszerzenia plik
manifest.json
zawiera czytelną sekcjęname
, która pomaga zidentyfikować rozszerzenie.
Użyj programu do archiwizacji lub rozpakowywania plików
Przejdź do Sklepu Chrome Web Store i pobierz rozszerzenie. Plik będzie miał rozszerzenie .crx
.
Zmień rozszerzenie pliku z .crx
na .zip
.
Użyj dowolnego programu do archiwizacji plików (np. WinRAR, 7-Zip itp.), aby rozpakować 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 rozszerzenie bez pakietu...".
Przejdź do katalogu z rozszerzeniem.
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
Mimo że rozszerzenia przeglądarki mają ograniczoną powierzchnię ataku, niektóre z nich mogą zawierać luki bezpieczeństwa lub potencjalne ulepszenia zabezpieczeń. Oto najczęstsze z nich:
- Ograniczaj jak najbardziej żądane
permissions
- Ograniczaj jak najbardziej
host_permissions
- Użyj silnej
content_security_policy
- Ograniczaj jak najbardziej
externally_connectable
, jeśli nie jest to konieczne i możliwe, nie pozostawiaj go domyślnie, określ{}
- Jeśli tutaj wymieniony jest URL podatny na XSS lub przejęcie, atakujący będzie mógł wysyłać wiadomości bezpośrednio do skryptów w tle. Bardzo potężne obejście.
- Ograniczaj jak najbardziej
web_accessible_resources
, nawet jeśli jest to możliwe, pozostaw puste. - Jeśli
web_accessible_resources
nie jest puste, sprawdź ClickJacking - Jeśli występuje jakakolwiek komunikacja z strony internetowej do rozszerzenia, sprawdź pod kątem podatności na XSS spowodowanej w komunikacji.
- Jeśli używane są wiadomości POST, sprawdź pod kątem podatności na wiadomości POST.
- Jeśli Skrypt zawartości ma dostęp do szczegółów DOM, sprawdź, czy nie wprowadza XSS, jeśli zostaną zmodyfikowane przez stronę internetową
- Zwróć szczególną uwagę, jeśli ta komunikacja jest również zaangażowana w komunikację Skryptu zawartości -> Skryptu w tle
- Wrażliwe informacje nie powinny być przechowywane w kodzie rozszerzenia przeglądarki
- Wrażliwe informacje nie powinny być przechowywane w pamięci rozszerzenia przeglądarki
Narzędzia
Tarnish
- Pobiera dowolne rozszerzenie Chrome z podanego linku do sklepu Chrome.
- Przeglądarka manifest.json: wyświetla wersję JSON w czytelnej formie manifestu rozszerzenia.
- Analiza odcisków palców: Wykrywanie web_accessible_resources i automatyczne generowanie JavaScriptu do odcisków palców rozszerzenia Chrome.
- Analiza potencjalnego Clickjackingu: Wykrywanie stron HTML rozszerzenia z dyrektywą web_accessible_resources. Są one potencjalnie podatne na clickjacking w zależności od celu stron.
- Przeglądarka ostrzeżeń o uprawnieniach: wyświetla listę wszystkich ostrzeżeń dotyczących uprawnień Chrome, które zostaną wyświetlone po próbie zainstalowania rozszerzenia przez użytkownika.
- Niebezpieczne funkcje: pokazuje lokalizację niebezpiecznych funkcji, które mogą być potencjalnie wykorzystane przez atakującego (np. funkcje takie jak innerHTML, chrome.tabs.executeScript).
- Punkty wejścia: pokazuje, gdzie rozszerzenie przyjmuje dane od użytkownika/zewnętrznych źródeł. Jest to przydatne do zrozumienia powierzchni ataku rozszerzenia i poszukiwania potencjalnych punktów do przesyłania złośliwie spreparowanych danych do rozszerzenia.
- Zarówno skanery Niebezpiecznych funkcji, jak i Punkty wejścia mają następujące funkcje dla wygenerowanych alertów:
- Istotny fragment kodu i linia, która spowodowała alert.
- Opis problemu.
- Przycisk "Wyświetl plik", aby wyświetlić pełny plik źródłowy zawierający kod.
- Ścieżka pliku, który wywołał alert.
- Pełny URI rozszerzenia Chrome dla pliku, który wywołał alert.
- Rodzaj pliku, taki jak skrypt strony w tle, skrypt zawartości, akcja przeglądarki itp.
- Jeśli podatna linia znajduje się w pliku JavaScript, ścieżki wszystkich stron, na których jest ona dołączona, oraz status web_accessible_resource tych stron.
- Analizator i sprawdzark
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLAN SUBSKRYPCJI!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi trikami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów github.