Blog 24/7

XXE

TAB. 1Hasłobez tłumaczenia
Po angielskuXML external entity (XXE)
Którą formą pisaćbez tłumaczenia Skrót, nazwa własna albo nazwa standardu — nie tłumaczymy w ogóle.
Inne formyXML External Entity · XXE injection · wstrzyknięcie encji zewnętrznej XML
KategoriaPodatności i klasy błędów

XXE (XML External Entity) to podatność, w której aplikacja przetwarza dokument XML zawierający encje z adresami URI wskazującymi zasoby spoza zamierzonego obszaru kontroli i wstawia te zasoby do wyniku [1]. OWASP opisuje XXE jako atak na aplikacje parsujące XML, w którym niezaufany dokument z odwołaniem do encji zewnętrznej trafia do słabo skonfigurowanego parsera [2]. W zestawieniu OWASP Top 10 z 2017 roku XXE miało osobną kategorię A4 [3]. W katalogu CWE odpowiada mu słabość CWE-611 [1].

Jak działa

Dokument XML może zawierać definicję typu dokumentu (DTD), a w niej deklaracje encji. Encja może wskazywać adres URI, którego treść parser pobiera i wstawia do dokumentu do dalszego przetwarzania [1]. Jeżeli parser rozwija takie encje, atakujący decyduje, jaki zasób zostanie odczytany: plik lokalny przez schemat file:// albo adres sieciowy przez http:// [1]. Gdy aplikacja odsyła wynik parsowania użytkownikowi, odczytana treść wraca do atakującego [1].

Warunki są dwa. Atakujący musi dostarczyć XML, na przykład przesyłając plik albo wstawiając treść do dokumentu XML, a parser musi mieć włączone przetwarzanie encji zewnętrznych [3]. OWASP zaznacza, że podatny może być kod samej aplikacji, jej zależności albo integracje z innymi systemami [3]. Źródłem XML nie musi więc być formularz: bywa nim plik przesłany przez użytkownika, odpowiedź zewnętrznej usługi albo metadane osadzone w pliku multimedialnym. Dlatego ustawienia parsera trzeba sprawdzać także w bibliotekach, nie tylko we własnym kodzie. Przebieg pokazuje schemat poniżej.

RYS. 1Odczyt pliku przez encję zewnętrzną

Skutki

MITRE wymienia trzy grupy skutków, a OWASP dodaje do nich skanowanie portów z hosta, na którym działa parser [1] [2].

SkutekMechanizmPokrewne hasło
odczyt dowolnych plikówencja ze schematem file:// [1]ujawnienie informacji wrażliwych
żądania z serweraencja ze schematem http:// [1]SSRF (Server-Side Request Forgery) [2]
wyczerpanie zasobówencja wskazująca duży plik albo niekończący się strumień [1]atak odmowy usługi [2]
rozpoznanie sieciskanowanie portów z hosta parsera [2]skanowanie portów

Przez żądania z serwera atakujący dociera do systemów, do których z zewnątrz nie ma dostępu [1]. Sekurak opisywał już w 2014 roku wykorzystanie XXE do ataku typu path traversal, do zapytań HTTP i FTP z poziomu serwera oraz do skanowania sieci lokalnej [8]. Ten sam tekst pokazuje, że atakujący potrafi obejść ograniczenia odczytu, kodując treść pliku filtrem base64 w PHP [8]. OWASP w liście Top 10 z 2017 roku zbiera skutki w jednym zdaniu: wyciąganie danych, zdalne żądania z serwera, skanowanie systemów wewnętrznych, odmowa usługi i inne ataki [3].

W WordPressie

XML pojawia się w WordPressie w kilku miejscach: w interfejsie XML-RPC, w importerach treści i w metadanych przesyłanych plików. Najlepiej opisanym przypadkiem jest podatność CVE-2021-29447 w Bibliotece mediów [7].

Według analizy SonarSource WordPress używał biblioteki getID3 do odczytu metadanych z przesyłanych plików audio, a fragment iXML w pliku WAV parsował funkcją simplexml_load_string() z flagą LIBXML_NOENT [5]. Nazwa flagi myli: w rzeczywistości włącza ona podstawianie encji [5]. Wcześniej kod wywoływał libxml_disable_entity_loader(true), ale dla PHP 8 to wywołanie usunięto, bo funkcja została w tej wersji wycofana [5]. Dokumentacja PHP podaje, że od libxml 2.9.0 podstawianie encji jest domyślnie wyłączone, chyba że kod sam włączy je flagą LIBXML_NOENT, LIBXML_DTDVALID albo LIBXML_DTDLOAD [4]. Właśnie ta flaga ponownie otworzyła drogę do XXE [5].

Do ataku wystarczało konto z prawem przesyłania plików, na przykład autora [7]; zob. role i uprawnienia użytkowników. SonarSource wskazało, że niższe uprawnienia wystarczą w połączeniu z inną podatnością albo wtyczką pozwalającą gościom przesyłać media [5]. Skutkiem mógł być odczyt pliku wp-config.php z danymi dostępu do bazy i kluczami uwierzytelniania albo SSRF [5], dlatego po takim incydencie zmienia się klucze bezpieczeństwa i sole i hasło bazy; zob. też utwardzanie pliku wp-config.php.

Jak się bronić

OWASP uznaje za najbezpieczniejsze całkowite wyłączenie DTD, bo chroni ono także przed atakiem odmowy usługi typu Billion Laughs [2]. Inne zalecenia z listy OWASP Top 10 2017 to prostsze formaty danych, takie jak JSON, wyłączenie encji zewnętrznych i DTD we wszystkich parserach XML, walidacja wejścia po stronie serwera oraz sprawdzanie przesyłanego XML schematem XSD [3]. Jako warstwy dodatkowe OWASP wymienia narzędzia SAST i WAF [3].

W PHP ściągawka OWASP zaleca dla wersji starszych niż 8.0 wywołanie libxml_set_external_entity_loader(null), a o PHP 8.0 i nowszym pisze, że domyślnie zapobiega XXE [2]. Przypadek WordPressa pokazuje granicę tej ochrony: flagi parsera mogą ją wyłączyć [5]. Praktyczne zasady:

  • nie włączać flagi LIBXML_NOENT ani ładowania DTD, jeśli nie jest to konieczne [4];
  • dla starszych wersji PHP wyłączać ładowanie encji zewnętrznych warunkowo, jak pokazuje dokumentacja PHP [4];
  • traktować metadane przesyłanych plików jak dane niezaufane i przepuszczać je przez sanityzację;
  • utrzymywać wspierane wersje PHP; zob. koniec wsparcia dla wersji PHP.
// Wzorzec z dokumentacji PHP: tylko dla PHP starszego niż 8.0
if ( PHP_VERSION_ID < 80000 ) {
    libxml_disable_entity_loader( true );
}
// Parsowanie bez flagi LIBXML_NOENT
$xml = simplexml_load_string( $dane );

Historia i przykłady

Lista MITRE zawiera między innymi CVE-2012-2239, czyli XXE w aplikacji PHP pozwalające odczytać plik konfiguracyjny, oraz CVE-2022-42745 w oprogramowaniu rekrutacyjnym [1].

W WordPressie poprawkę CVE-2021-29447 przyniosła wersja 5.7.1 z 15 kwietnia 2021 roku, opisana jako usunięcie podatności XXE w Bibliotece mediów dotyczącej PHP 8, zgłoszonej przez SonarSource [6]. WPScan podaje jako poprawione wersje 5.7.1, 5.6.3 i 5.0.12 oraz ocenę CVSS 7,5 [7]. Łatka przywróciła wywołanie libxml_disable_entity_loader() także dla PHP 8, z operatorem tłumienia błędów, żeby nie generować ostrzeżeń o wycofanej funkcji [5]. Poprawki trafiły do witryn przez aktualizację rdzenia.

TAB. 2

Przypisy

8
  1. [1] CWE-611: Improper Restriction of XML External Entity Reference · MITRE
  2. [2] XML External Entity Prevention Cheat Sheet · OWASP
  3. [3] A4:2017 – XML External Entities (XXE) · OWASP
  4. [4] libxml_disable_entity_loader — PHP Manual · The PHP Group
  5. [5] WordPress 5.7 XXE Vulnerability · SonarSource
  6. [6] WordPress 5.7.1 Security and Maintenance Release · WordPress.org
  7. [7] WordPress 5.6-5.7 – Authenticated XXE Within the Media Library Affecting PHP 8 · WPScan
  8. [8] Problemy z XXE (XML eXternal Entity) · Sekurak
TAB. 3

Hasła w tym artykule

17

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