mass assignment
| Po angielsku | mass assignment |
|---|---|
| Którą formą pisać | po angielsku Polski odpowiednik istnieje, ale w praktyce nikt tak nie pisze. Zostaw angielski, polski trzymaj jako synonim. |
| Inne formy | masowe przypisanie · podatność masowego przypisania |
| Kategoria | Podatności i klasy błędów |
Mass assignment to podatność, w której aplikacja przyjmuje z żądania wiele pól naraz i przepisuje je na obiekt albo rekord w bazie, nie kontrolując, które z nich wolno zmieniać. MITRE opisuje ją jako słabość CWE-915: produkt otrzymuje dane określające atrybuty do ustawienia w obiekcie, ale nie ogranicza, które atrybuty mogą zostać zmodyfikowane [1]. Problem pojawia się, gdy obiekt ma atrybuty przeznaczone wyłącznie do użytku wewnętrznego [1].
Jak działa
OWASP wyjaśnia, że frameworki pozwalają automatycznie wiązać parametry żądania HTTP ze zmiennymi albo obiektami w kodzie [2]. To wygodne, bo formularz z dziesięcioma polami zapisuje się jedną instrukcją. Atakujący może jednak dopisać parametr, którego programista nie przewidział [2]. Klasyczny przykład z OWASP: formularz przyjmuje identyfikator użytkownika, hasło i e-mail, a obiekt użytkownika ma też pole isAdmin; dodatkowy parametr isAdmin=true nadaje uprawnienia administratora [2].
Do skutecznego ataku atakujący musi znać albo odgadnąć nazwę wrażliwego pola, na przykład z kodu źródłowego [2]. W oprogramowaniu open source, takim jak wtyczki WordPressa, nazwy pól są jawne. Przebieg pokazuje schemat poniżej.
Nazwy i odmiany
Ta sama słabość nosi różne nazwy w zależności od technologii [1] [2].
| Nazwa | Gdzie używana | Uwagi |
|---|---|---|
| mass assignment | Ruby on Rails, NodeJS [2] | nazwa od funkcji Rails [1] |
| autobinding | Spring MVC, ASP.NET MVC [1] | wiązanie parametrów z modelem |
| object injection | PHP [2] | u części badaczy dotyczy unserialize() [1] |
Nazwa „object injection” w PHP bywa myląca. W świecie WordPressa oznacza zwykle PHP object injection, czyli skutek deserializacji niezaufanych danych, a nie przepisywanie pól formularza. W API OWASP łączy mass assignment z nadmiernym ujawnianiem danych w jedną kategorię API3:2023, dotyczącą autoryzacji na poziomie właściwości obiektu [3]. Punkt końcowy jest podatny, jeśli pozwala użytkownikowi zmienić, dodać albo usunąć wartość wrażliwej właściwości, do której nie powinien mieć dostępu [3]. Mass assignment jest więc szczególnym przypadkiem Broken Access Control.
W WordPressie
W WordPressie odpowiednikiem automatycznego wiązania jest kod wtyczki, który bierze całą tablicę $_POST albo parametry żądania REST i przekazuje je do funkcji zapisujących użytkownika lub jego metadane. Funkcja wp_insert_user() przyjmuje w tablicy danych między innymi pole role oraz meta_input, czyli tablicę dowolnych metadanych kluczowanych nazwą klucza [4]. Dokumentacja zaznacza, że pole role jest jednym z wyjątków, które nie mają powiązanego filtra [4]. Wtyczka, która przekaże do takiej funkcji niefiltrowane dane z formularza, pozwala wybrać sobie rolę.
Drugim miejscem jest niezabezpieczony punkt końcowy REST API. Podręcznik REST API zaleca deklarowanie argumentów w kluczu args, z opcjami required, sanitize_callback i validate_callback, tak aby główna funkcja przetwarzała już sprawdzone dane [5]. Od WordPressa 5.5 brak permission_callback wywołuje ostrzeżenie _doing_it_wrong [5]. Zadeklarowana lista argumentów pełni rolę listy dozwolonych pól, pod warunkiem że funkcja obsługi nie sięga po całą treść żądania.
Poniższy przykład zestawia oba podejścia.
// podatne: każdy klucz z formularza trafia do metadanych
foreach ( $_POST as $klucz => $wartosc ) {
update_user_meta( $user_id, $klucz, $wartosc );
}
// lista dozwolonych pól
$dozwolone = array( 'first_name', 'last_name', 'description' );
foreach ( $dozwolone as $klucz ) {
if ( isset( $_POST[ $klucz ] ) ) {
update_user_meta( $user_id, $klucz, sanitize_text_field( wp_unslash( $_POST[ $klucz ] ) ) );
}
}
Zagrożenia i skutki
MITRE wymienia jako skutki modyfikację danych aplikacji, zmianę logiki działania i wykonanie nieautoryzowanego kodu [1]. Wśród przykładów z bazy CVE podaje także CVE-2024-3283, czyli mass assignment w aplikacji opartej na dużym modelu językowym [1], co pokazuje, że klasa błędu nie zniknęła wraz ze starszymi frameworkami. OWASP w API3:2023 opisuje scenariusze z modyfikacją pól wewnętrznych, takich jak ceny albo ustawienia dostępu, oraz podniesienie uprawnień [3]. Najgroźniejszym skutkiem na stronie WordPress jest eskalacja uprawnień do administratora, a potem nieautoryzowane konto administratora używane jako stały punkt wejścia.
Jak się bronić
OWASP wskazuje trzy podejścia: listę dozwolonych pól, listę zabronionych pól i osobne obiekty transferu danych zawierające tylko pola edytowalne [2]. MITRE zaleca listy dozwolonych atrybutów zamiast list zabronionych [1]. W API OWASP dodaje: unikać automatycznego wiązania danych klienta z wewnętrznymi atrybutami i ograniczyć zmienialne właściwości do tych, które klient ma prawo aktualizować [3].
- lista dozwolonych kluczy przy każdym zapisie użytkownika i metadanych;
- sanityzacja każdego przyjętego pola;
- kontrola uprawnień przez weryfikację uprawnień przed zapisem, osobno dla pól wrażliwych, takich jak rola;
- przegląd kodu wtyczek pod kątem przekazywania całych tablic żądania do funkcji zapisu.
MITRE proponuje też zmianę konstrukcji kodu: zamiast dynamicznie ustalać, który atrybut zmienić, udostępnić tylko metody ustawiające te pola, które mają być zmienialne [1]. OWASP zauważa, że większość frameworków ma wbudowane mechanizmy list dozwolonych i obiektów transferu danych [2]. W WordPressie takim mechanizmem jest deklaracja args w trasie REST [5]. Lista zabronionych pól jest najsłabszą z tych metod, bo wystarczy jedno pominięte pole albo inny zapis tej samej nazwy.
Historia i przykłady
OWASP podaje przykład z 2012 roku: podatność w GitHubie pozwalała dodawać klucze publiczne do organizacji, których użytkownik nie był właścicielem [2].
W WordPressie najbardziej znanym przypadkiem jest wtyczka Ultimate Member, mająca wtedy ponad 200 000 aktywnych instalacji [6]. WPScan opisał 29 czerwca 2023 roku kampanię aktywnie wykorzystującą podatność w tej wtyczce [6]. Wtyczka ograniczała metadane ustawiane przy rejestracji listą zabronionych kluczy, a atakujący wykorzystali różnice między tą listą a obsługą metadanych w WordPressie, żeby zmienić pole wp_capabilities, w którym zapisane są role i uprawnienia [6]. Po utworzeniu kont administratora logowali się przez wp-login.php i wgrywali złośliwe wtyczki [6]. Poprawkę przyniosła wersja 2.6.7 [6]. WPScan podsumował incydent jako argument za listami dozwolonych wartości zamiast list zabronionych [6]; zob. też podatność we wtyczce.
Przypisy
6- [1] CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes · MITRE
- [2] Mass Assignment Cheat Sheet · OWASP
- [3] API3:2023 Broken Object Property Level Authorization · OWASP
- [4] wp_insert_user() — Code Reference · WordPress.org
- [5] Adding Custom Endpoints — REST API Handbook · WordPress.org
- [6] Hacking Campaign Actively Exploiting Ultimate Member Plugin · WPScan