Blog 24/7

prototype pollution

TAB. 1Hasłopo angielsku
Po angielskuprototype pollution
Którą formą pisaćpo angielsku Polski odpowiednik istnieje, ale w praktyce nikt tak nie pisze. Zostaw angielski, polski trzymaj jako synonim.
Inne formyzanieczyszczenie prototypu · zatruwanie prototypu
KategoriaPodatności i klasy błędów

Prototype pollution to podatność w JavaScripcie, która pozwala atakującemu dodawać dowolne właściwości do globalnych prototypów obiektów; właściwości te dziedziczą potem obiekty tworzone przez aplikację [1]. MITRE opisuje ją jako słabość CWE-1321: produkt przyjmuje dane określające atrybuty obiektu do ustawienia, ale nie kontroluje zmian atrybutów prototypu [2]. Po stronie przeglądarki prowadzi zwykle do DOM-based XSS, a po stronie serwera może skończyć się zdalnym wykonaniem kodu [1].

Jak działa

W JavaScripcie prawie każdy obiekt dziedziczy właściwości po wspólnym prototypie. Jeśli do tego prototypu trafi nowa właściwość, zobaczą ją wszystkie obiekty, które same jej nie mają. Aplikacja, która sprawdza na przykład options.isAdmin albo config.url, dostaje wtedy wartość podstawioną przez atakującego, choć nigdzie jej nie ustawiała.

Według PortSwigger błąd powstaje najczęściej, gdy funkcja rekurencyjnie scala obiekt kontrolowany przez użytkownika z istniejącym obiektem i nie oczyszcza kluczy [1]. Klucz __proto__ nie zostaje wtedy potraktowany jak zwykła nazwa pola, tylko jako odwołanie do prototypu, więc scalanie zapisuje wartości w prototypie zamiast w obiekcie docelowym [1]. MITRE wymienia jako niebezpieczne atrybuty __proto__, constructor i prototype [2].

Dane do scalenia mogą pochodzić z parametrów zapytania i fragmentu adresu URL, z danych JSON przetwarzanych funkcją JSON.parse() albo z komunikatów wymienianych między oknami przeglądarki [1]. W przypadku JSON-u parser traktuje __proto__ jak zwykły klucz tekstowy; specjalnego znaczenia nabiera on dopiero przy późniejszym przypisaniu do obiektu [1]. Dlatego ta sama struktura danych bywa bezpieczna w jednym miejscu kodu i groźna w innym.

PortSwigger wskazuje trzy elementy potrzebne do skutecznego ataku [1].

RYS. 1Elementy ataku prototype pollution
ElementZnaczeniePrzykłady
źródło (source)dane kontrolowane przez użytkownika [1]parametry i fragment adresu, JSON, komunikaty między oknami [1]
ujście (sink)funkcja albo element DOM, który pozwala wykonać kod [1]wstawianie HTML, wykonanie skryptu
gadżet (gadget)właściwość używana niebezpiecznie i dziedziczona po prototypie [1]domyślna opcja biblioteki

W WordPressie

WordPress przez lata dołączał do rdzenia bibliotekę jQuery, a z niej korzystały motywy i wtyczki. Wydanie jQuery 3.4.0 z 10 kwietnia 2019 roku naprawiło nieoczekiwane zachowanie funkcji jQuery.extend w trybie głębokiego scalania: jeśli niezaufany obiekt źródłowy zawierał wyliczalną właściwość __proto__, mógł rozszerzyć natywny Object.prototype [3]. Po poprawce jQuery.extend nie zapisuje już właściwości o nazwie __proto__ [3]. MITRE podaje ten błąd jako przykład słabości CWE-1321 pod numerem CVE-2019-11358 [2].

WordPress dołączał wtedy własną, starszą wersję biblioteki. 17 maja 2019 roku do repozytorium WordPressa trafiła zmiana, która przenosi (backport) poprawkę z jQuery 3.4.0 do dołączanej wersji biblioteki [4]. Numer wersji dołączanej biblioteki nie mówi więc sam w sobie, czy poprawka jest obecna. W czerwcu 2020 roku zespół rdzenia ogłosił plan aktualizacji: usunięcie jQuery Migrate 1.x w wersji 5.5 i przejście na najnowsze jQuery w wersji 5.6 [7].

Ryzyko nie kończy się na rdzeniu. Wtyczki i motywy często dołączają własne kopie bibliotek JavaScript, także przestarzałe; zob. podatność we wtyczce, podatność w motywie i Vulnerable and Outdated Components.

Zagrożenia i skutki

MITRE wymienia dwa główne skutki [2]. Pierwszy to wpływ na dane: atakujący wstrzykuje atrybuty używane przez inne składniki aplikacji, co może dać nieuprawniony odczyt albo zmianę danych. Drugi to awaria: nadpisanie istniejącego atrybutu wartością niezgodnego typu może spowodować awarię aplikacji [2], co w usłudze serwerowej oznacza atak odmowy usługi (denial of service).

W przeglądarce prototype pollution prowadzi zwykle do XSS (Cross-Site Scripting) opartego na DOM [1]. Po stronie serwera, w aplikacjach Node.js, może prowadzić do zdalnego wykonania kodu (RCE) [1]. W obu przypadkach sam ładunek (payload) bywa niewinny: to tylko klucz i wartość w JSON-ie. Szkodę wyrządza dopiero kod aplikacji, który tę wartość później odczytuje.

Jak się bronić

Zalecenia PortSwigger, MITRE i OWASP są zbieżne [1] [2] [5]:

  • Oczyszczanie kluczy. Przy scalaniu i kopiowaniu obiektów odrzucać klucze __proto__, constructor i prototype [2]. To odmiana sanityzacji danych wejściowych.
  • Obiekty bez prototypu. Tworzyć słowniki funkcją Object.create(null), która daje obiekt niedziedziczący po Object.prototype [5].
  • Map i Set. OWASP zaleca używać new Map() albo new Set() zamiast literałów obiektów do przechowywania danych z zewnątrz [5].
  • Zamrożenie prototypu. Object.freeze(Object.prototype) blokuje zmiany prototypu, choć może psuć zgodność z niektórymi bibliotekami [2] [5].
  • Node.js. Flaga --disable-proto=delete usuwa właściwość __proto__; OWASP zaznacza, że zanieczyszczenie przez constructor.prototype jest nadal możliwe, więc to tylko dodatkowa warstwa [5].

Fragment poniżej pokazuje obronne scalanie z filtrem kluczy.

const BLOCKED = new Set(['__proto__', 'constructor', 'prototype']);
function safeMerge(target, source) {
  for (const key of Object.keys(source)) {
    if (BLOCKED.has(key)) continue;
    target[key] = source[key];
  }
  return target;
}

Przy stronach WordPress najprostszym krokiem jest aktualność rdzenia, wtyczek i motywów razem z bibliotekami, które dołączają. Pomaga w tym SBOM (wykaz komponentów oprogramowania) albo przynajmniej lista zależności JavaScript. CSP (Content Security Policy) ogranicza skutki, gdy zanieczyszczenie prowadzi do XSS.

Historia i przykłady

Sekurak w październiku 2019 roku opisał, że Michał Bentkowski przygotował exploit dla Kibany, aplikacji opartej o Node.js, wykorzystujący podatność prototype pollution CVE-2019-7609 do wykonania dowolnego kodu na systemie operacyjnym [6]. Sekurak określił ją jako dość mało znaną klasę podatności [6]. Pracę zaprezentowano na konferencji OWASP Day [6]. Wśród przykładów podawanych przez MITRE są też CVE-2018-3721, CVE-2019-10744 i CVE-2020-8203, związane ze scalaniem obiektów, przypisywaniem wartości domyślnych albo ustawianiem atrybutów według ścieżki z kropkami [2].

TAB. 2

Przypisy

7
  1. [1] Prototype pollution · PortSwigger Web Security Academy
  2. [2] CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution') · MITRE
  3. [3] jQuery 3.4.0 Released · jQuery Foundation
  4. [4] jQuery: bring jquery.js back into the WordPress SVN repo and backport the patch from 3.4.0 (commit 1406654) · WordPress (wordpress-develop, GitHub)
  5. [5] Prototype Pollution Prevention Cheat Sheet · OWASP
  6. [6] RCE w aplikacji opartej o Node.js (Kibana & Prototype Pollution & CVE-2019-7609) · Sekurak
  7. [7] Updating jQuery version shipped with WordPress · Make WordPress Core
TAB. 3

Hasła w tym artykule

12

Wszystkie kategorie → · Hasło w słowniku →

Blog 24/7
05.11CISA i FBI wzywają do zabezpieczenia sterowników chłodzenia po atakach w Europietherecord.media05.11Midnight Blizzard atakowała iPhone'y i Androidy przez zainfekowane strony w Europie i USAsecurityweek.com05.11APT29 kradła dane z iPhone'ów i Androidów przez przejęte i podrobione stronytherecord.media05.11Grupa APT29 przejęła skrypt Plerdy i atakowała niezałatane iPhone'y i Androidythehackernews.com05.11Microsoft wykrył 7,3 mld wiadomości phishingowych w III kwartale 2026microsoft.com05.11DigiCert ujawnia wyciek danych klientów i skanów dokumentów tożsamościbleepingcomputer.com05.11CWPdoor podmienia serwer cwpsrv w Control Web Panel i otwiera tylne wejście do Linuksableepingcomputer.com05.11Brytyjskie NCSC ostrzega, że narzędzia AI zwiększyły liczbę wykrywanych luk zero-daythehackernews.com05.11Skaner RootEvidence sprawdza starą lukę w Cisco IOS i dodaje nagłówki Opt-Outisc.sans.edu05.11Włamanie do portalu grantowego Norad, zagrożone dane 20 614 użytkownikówhelpnetsecurity.com