NodeJS - __proto__ & prototype Pollution
Obiekty w JavaScript
Obiekty w JavaScript są zasadniczo zbiorami par klucz-wartość, znanych jako właściwości. Obiekt można utworzyć za pomocą Object.create
z null
jako argumentem, aby uzyskać pusty obiekt. Ta metoda pozwala na tworzenie obiektu bez dziedziczonych właściwości.
Pusty obiekt jest podobny do pustego słownika, reprezentowanego jako {}
.
Funkcje i Klasy w JavaScript
W JavaScript klasy i funkcje są ze sobą ściśle powiązane, a funkcje często pełnią rolę konstruktorów dla klas. Pomimo braku natywnego wsparcia dla klas w JavaScript, konstruktory mogą naśladować zachowanie klas.
Prototypy w JavaScript
JavaScript pozwala na modyfikację, dodawanie lub usuwanie atrybutów prototypu w czasie rzeczywistym. Ta elastyczność umożliwia dynamiczne rozszerzanie funkcjonalności klas.
Funkcje takie jak toString
i valueOf
mogą być zmieniane, aby zmienić ich zachowanie, co pokazuje elastyczny charakter systemu prototypów w JavaScript.
Dziedziczenie
W programowaniu opartym na prototypach, właściwości/metody są dziedziczone przez obiekty z klas. Klasy te są tworzone poprzez dodawanie właściwości/metod do instancji innej klasy lub do pustego obiektu.
Należy zauważyć, że gdy właściwość jest dodawana do obiektu, który służy jako prototyp dla innych obiektów (takich jak myPersonObj
), obiekty dziedziczące uzyskują dostęp do tej nowej właściwości. Jednak ta właściwość nie jest automatycznie wyświetlana, chyba że jest wyraźnie wywołana.
__proto__ zanieczyszczenie
Badanie zanieczyszczenia prototypu w JavaScript
Obiekty JavaScript są definiowane przez pary klucz-wartość i dziedziczą z prototypu obiektu JavaScript. Oznacza to, że modyfikacja prototypu obiektu może wpływać na wszystkie obiekty w środowisku.
Użyjmy innego przykładu, aby to zilustrować:
Dostęp do prototypu obiektu jest możliwy przez:
Dodając właściwości do prototypu obiektu, każdy obiekt JavaScript odziedziczy te nowe właściwości:
zanieczyszczenie prototypu
W scenariuszu, w którym użycie __proto__
jest ograniczone, modyfikacja prototypu funkcji jest alternatywą:
To wpływa tylko na obiekty utworzone z konstruktora Vehicle
, nadając im właściwości beep
, hasWheels
, honk
i isElectric
.
Dwie metody globalnego wpływania na obiekty JavaScript poprzez zanieczyszczenie prototypu obejmują:
Zanieczyszczenie
Object.prototype
bezpośrednio:
Zanieczyszczanie prototypu konstruktora dla powszechnie używanej struktury:
Po tych operacjach każdy obiekt JavaScript może wykonywać metody goodbye
i greet
.
Zanieczyszczanie innych obiektów
Z klasy do Object.prototype
W scenariuszu, w którym możesz zanieczyścić konkretny obiekt i musisz dostać się do Object.prototype
, możesz go wyszukać za pomocą czegoś takiego jak poniższy kod:
Zanieczyszczenie elementów tablicy
Zauważ, że ponieważ możesz zanieczyścić atrybuty obiektów w JS, jeśli masz dostęp do zanieczyszczenia tablicy, możesz również zanieczyścić wartości tablicy dostępne za pomocą indeksów (zauważ, że nie możesz nadpisać wartości, więc musisz zanieczyścić indeksy, które są w jakiś sposób używane, ale nie zapisywane).
Zanieczyszczenie elementów Html
Podczas generowania elementu HTML za pomocą JS możliwe jest nadpisanie atrybutu innerHTML
, aby umożliwić zapis dowolnego kodu HTML. Pomysł i przykład z tego opracowania.
Przykłady
Podstawowy przykład
Zanieczyszczenie prototypu występuje z powodu błędu w aplikacji, który pozwala na nadpisywanie właściwości w Object.prototype
. Oznacza to, że ponieważ większość obiektów dziedziczy swoje właściwości z Object.prototype
Najłatwiejszym przykładem jest dodanie wartości do niezdefiniowanej atrybutu obiektu, który ma być sprawdzany, jak:
Jeśli atrybut admin
jest niezdefiniowany, możliwe jest nadużycie PP i ustawienie go na True za pomocą czegoś takiego:
Mechanizm stojący za tym polega na manipulowaniu właściwościami w taki sposób, że jeśli atakujący ma kontrolę nad określonymi danymi wejściowymi, może zmodyfikować prototyp wszystkich obiektów w aplikacji. Ta manipulacja zazwyczaj polega na ustawieniu właściwości __proto__
, która w JavaScript jest tożsama z bezpośrednią modyfikacją prototypu obiektu.
Warunki, w jakich ten atak może być pomyślnie przeprowadzony, jak opisano w konkretnej studii, obejmują:
Wykonywanie rekurencyjnego scalania.
Definiowanie właściwości na podstawie ścieżki.
Klonowanie obiektów.
Funkcja nadpisania
Zanieczyszczenie prototypu do RCE
Prototype Pollution to RCEInne ładunki:
Zanieczyszczenie prototypu po stronie klienta do XSS
Client Side Prototype PollutionCVE-2019–11358: Atak zanieczyszczenia prototypu przez jQuery $ .extend
Po więcej szczegółów sprawdź ten artykuł W jQuery funkcja $ .extend
może prowadzić do zanieczyszczenia prototypu, jeśli funkcja głębokiego kopiowania jest wykorzystywana niewłaściwie. Funkcja ta jest powszechnie używana do klonowania obiektów lub łączenia właściwości z obiektu domyślnego. Jednak w przypadku niewłaściwej konfiguracji, właściwości przeznaczone dla nowego obiektu mogą zostać przypisane do prototypu. Na przykład:
Ta podatność, zidentyfikowana jako CVE-2019–11358, ilustruje, jak głębokie kopiowanie może nieumyślnie modyfikować prototyp, prowadząc do potencjalnych zagrożeń bezpieczeństwa, takich jak nieautoryzowany dostęp administratora, jeśli właściwości takie jak isAdmin
są sprawdzane bez odpowiedniej weryfikacji istnienia.
CVE-2018–3721, CVE-2019–10744: Atak zanieczyszczenia prototypu przez lodash
Po więcej szczegółów sprawdź ten artykuł
Lodash napotkał podobne podatności na zanieczyszczenie prototypu (CVE-2018–3721, CVE-2019–10744). Problemy te zostały rozwiązane w wersji 4.17.11.
Inny samouczek z CVE
Narzędzia do wykrywania zanieczyszczenia prototypu
Server-Side-Prototype-Pollution-Gadgets-Scanner: Rozszerzenie Burp Suite zaprojektowane do wykrywania i analizy podatności na zanieczyszczenie prototypu po stronie serwera w aplikacjach internetowych. To narzędzie automatyzuje proces skanowania żądań w celu zidentyfikowania potencjalnych problemów z zanieczyszczeniem prototypu. Wykorzystuje znane gadżety - metody wykorzystywania zanieczyszczenia prototypu do wykonywania szkodliwych działań - szczególnie koncentrując się na bibliotekach Node.js.
server-side-prototype-pollution: To rozszerzenie identyfikuje podatności na zanieczyszczenie prototypu po stronie serwera. Wykorzystuje techniki opisane w zanieczyszczeniu prototypu po stronie serwera.
Zanieczyszczenie prototypu AST w NodeJS
NodeJS szeroko wykorzystuje Drzewa Składni Abstrakcyjnej (AST) w JavaScript do funkcji takich jak silniki szablonów i TypeScript. Ta sekcja bada podatności związane z zanieczyszczeniem prototypu w silnikach szablonów, szczególnie Handlebars i Pug.
Analiza podatności Handlebars
Silnik szablonów Handlebars jest podatny na atak zanieczyszczenia prototypu. Ta podatność wynika z konkretnych funkcji w pliku javascript-compiler.js
. Funkcja appendContent
, na przykład, konkatenacja pendingContent
, jeśli jest obecna, podczas gdy funkcja pushSource
resetuje pendingContent
do undefined
po dodaniu źródła.
Proces eksploatacji
Eksploatacja wykorzystuje AST (Drzewo Składni Abstrakcyjnej) generowane przez Handlebars, wykonując następujące kroki:
Manipulacja parserem: Początkowo parser, za pośrednictwem węzła
NumberLiteral
, wymusza, aby wartości były numeryczne. Zanieczyszczenie prototypu może to obejść, umożliwiając wstawienie nienumerycznych ciągów.Obsługa przez kompilator: Kompilator może przetwarzać obiekt AST lub szablon ciągu. Jeśli
input.type
równa sięProgram
, wejście jest traktowane jako wstępnie przetworzone, co można wykorzystać.Wstrzyknięcie kodu: Poprzez manipulację
Object.prototype
, można wstrzyknąć dowolny kod do funkcji szablonu, co może prowadzić do zdalnego wykonania kodu.
Przykład ilustrujący eksploatację podatności Handlebars:
Ten kod pokazuje, jak atakujący może wstrzyknąć dowolny kod do szablonu Handlebars.
External Reference: Zidentyfikowano problem związany z zanieczyszczeniem prototypu w bibliotece 'flat', jak szczegółowo opisano tutaj: Issue on GitHub.
External Reference: Problem związany z zanieczyszczeniem prototypu w bibliotece 'flat'
Przykład wykorzystania zanieczyszczenia prototypu w Pythonie:
Pug Vulnerability
Pug, inny silnik szablonów, stoi przed podobnym ryzykiem zanieczyszczenia prototypu. Szczegółowe informacje są dostępne w dyskusji na temat AST Injection in Pug.
Przykład zanieczyszczenia prototypu w Pug:
Środki zapobiegawcze
Aby zmniejszyć ryzyko zanieczyszczenia prototypu, można zastosować poniższe strategie:
Niemutowalność obiektów:
Object.prototype
można uczynić niemutowalnym, stosującObject.freeze
.Walidacja wejścia: Wejścia JSON powinny być rygorystycznie walidowane w odniesieniu do schematu aplikacji.
Bezpieczne funkcje scalania: Należy unikać niebezpiecznego użycia rekurencyjnych funkcji scalania.
Obiekty bez prototypu: Obiekty bez właściwości prototypu można tworzyć za pomocą
Object.create(null)
.Użycie Map: Zamiast
Object
, należy używaćMap
do przechowywania par klucz-wartość.Aktualizacje bibliotek: Łatki bezpieczeństwa można wprowadzać poprzez regularne aktualizowanie bibliotek.
Narzędzia lintera i analizy statycznej: Używaj narzędzi takich jak ESLint z odpowiednimi wtyczkami, aby wykrywać i zapobiegać lukom w zanieczyszczeniu prototypu.
Przeglądy kodu: Wprowadź dokładne przeglądy kodu, aby zidentyfikować i usunąć potencjalne ryzyka związane z zanieczyszczeniem prototypu.
Szkolenie w zakresie bezpieczeństwa: Edukuj programistów o ryzyku zanieczyszczenia prototypu i najlepszych praktykach pisania bezpiecznego kodu.
Ostrożne korzystanie z bibliotek: Bądź ostrożny podczas korzystania z bibliotek osób trzecich. Oceń ich bezpieczeństwo i przeglądaj ich kod, szczególnie te, które manipulują obiektami.
Ochrona w czasie wykonywania: Wprowadź mechanizmy ochrony w czasie wykonywania, takie jak użycie pakietów npm skoncentrowanych na bezpieczeństwie, które mogą wykrywać i zapobiegać atakom zanieczyszczenia prototypu.
Odniesienia
Last updated