
Co znajdziesz w tym artykule?
- 1 Wprowadzenie do problemu / definicja luki
- 2 W skrócie
- 3 Kontekst / historia / powiązania
- 4 Analiza techniczna / szczegóły luki
- 5 Praktyczne konsekwencje / ryzyko
- 6 Rekomendacje operacyjne / co zrobić teraz
- 7 Różnice / porównania z innymi przypadkami (jeśli dotyczy)
- 8 Podsumowanie / kluczowe wnioski
- 9 Źródła / bibliografia
Wprowadzenie do problemu / definicja luki
Na początku stycznia 2026 ujawniono krytyczną podatność w ekosystemie AdonisJS, dotyczącą pakietu npm @adonisjs/bodyparser. Luka została zarejestrowana jako CVE-2026-21440 i oceniona przez CNA (GitHub) na CVSS 4.0: 9.2 (Critical).
To klasyczny przypadek path traversal (CWE-22) w mechanizmie obsługi uploadu multipart/form-data, który w określonych warunkach umożliwia zdalnemu atakującemu zapis plików w dowolnej lokalizacji w systemie plików serwera (a w konsekwencji — czasem także eskalację do RCE).
W skrócie
- Co jest podatne:
@adonisjs/bodyparser(mechanizmMultipartFile.move(...)). - Wektor ataku: upload przez endpoint, który przyjmuje
multipart/form-data. - Sedno problemu: domyślne użycie niesanitowanej nazwy pliku pochodzącej od klienta oraz ryzykowne domyślne ustawienia w
move()(m.in. domyślne nadpisywanie). - Skutek: arbitrary file write (dowolny zapis/nadpisanie pliku); potencjalnie RCE, jeśli uda się nadpisać pliki ładowane/wykonywane przez aplikację.
- Naprawa: aktualizacja do
@adonisjs/bodyparser10.1.2 (stable) lub 11.0.0-next.6 (pre-release).
Kontekst / historia / powiązania
Informacja o luce pojawiła się publicznie w formie GitHub Security Advisory opublikowanego 2 stycznia 2026, a następnie została szerzej opisana m.in. w mediach branżowych 6 stycznia 2026.
Istotny kontekst z perspektywy ryzyka: advisory wskazuje, że dokumentacja pokazywała wcześniej przykłady prowadzące do użycia podatnej ścieżki (czyli „secure-by-default” nie zadziałało, a dodatkowo wzorce z docs mogły utrwalić ryzykowną praktykę).
Analiza techniczna / szczegóły luki
Gdzie jest błąd?
AdonisJS parsuje multipart/form-data przez BodyParser i udostępnia uploady jako obiekty MultipartFile. Problem dotyczy zachowania metody:
MultipartFile.move(location, options)
Jeżeli aplikacja wywołuje move() bez przekazania options.name, framework (w podatnych wersjach) domyślnie podstawiał nazwę pliku przesłaną przez klienta (client filename) i budował ścieżkę docelową w stylu path.join(location, name). Przy odpowiednio spreparowanej nazwie (np. z sekwencjami ../) atakujący może „wyjść” poza katalog uploadu i wskazać inną lokalizację zapisu.
Dodatkowo advisory podkreśla drugi element ryzyka: jeśli options.overwrite nie jest przekazane, domyślnie ustawione było na true, co ułatwia nadpisywanie istniejących plików.
Kiedy to działa w praktyce?
Wprost: potrzebny jest osiągalny endpoint uploadu, który:
- przyjmuje
multipart/form-data, oraz - używa
MultipartFile.move()w sposób podatny (bezoptionslub bez sanitacji nazwy pliku).
Co zmienia poprawka?
W wydaniu 10.1.2 (analogicznie w 11.0.0-next.6) wprowadzono zmianę: MultipartFile.move(location) nie używa już domyślnie nazwy pliku od klienta. Zamiast tego generowana jest losowa, unikalna nazwa oparta o uuid. To jest świadomie opisane jako breaking change, ale dostarczone w patchu, aby szybko „zamknąć” klasę ataków wynikającą z niebezpiecznego domyślnego zachowania.
Praktyczne konsekwencje / ryzyko
Najbardziej bezpośrednim skutkiem jest arbitrary file write: atakujący może doprowadzić do zapisu pliku w ścieżce, której programista nie przewidział — łącznie z nadpisaniem krytycznych plików, jeżeli proces ma odpowiednie uprawnienia.
RCE nie jest „gwarantowane”, ale scenariusz jest realistyczny, jeśli możliwe jest nadpisanie:
- kodu aplikacji,
- skryptów uruchomieniowych,
- konfiguracji ładowanej w runtime,
- plików, które zostaną później wykonane lub zinterpretowane przez aplikację/środowisko.
W praktyce poziom ryzyka zależy od:
- topologii wdrożenia (kontenery vs VM vs bare metal),
- praw dostępu użytkownika systemowego uruchamiającego node,
- tego, gdzie trzymane są uploady (czy katalog uploadu ma sensowne izolacje),
- czy endpoint uploadu jest publiczny oraz jak wygląda autoryzacja/limity.
Rekomendacje operacyjne / co zrobić teraz
1) Aktualizacja (najważniejsze)
- Zaktualizuj
@adonisjs/bodyparserdo 10.1.2 (lub nowszej) w gałęzi stabilnej. - Jeśli używasz pre-release 11.x: zaktualizuj do 11.0.0-next.6 (lub nowszej).
2) Szybki audyt kodu pod kątem podatnego wzorca
Priorytetowo przejrzyj miejsca, gdzie:
- przyjmujesz upload
multipart/form-data, - wywołujesz
MultipartFile.move(...)bez jawnegooptions.name, - dopuszczasz
overwrite: true(albo nie ustawiasz tego parametru).
3) Twarde zasady dla uploadów (defense-in-depth)
Nawet po aktualizacji:
- Przechowuj uploady poza webrootem (aby nie dało się ich od razu wykonywać/serwować jako kod).
- Stosuj allowlistę typów (MIME i/lub sniffing), limity rozmiaru, limity liczby plików.
- Używaj least privilege dla procesu Node.js (konto systemowe bez praw do katalogów aplikacji/konfiguracji).
- Rozważ read-only filesystem dla kontenera i osobny, izolowany wolumen tylko na uploady.
4) Monitoring i detekcja (co sprawdzić po stronie SOC/ops)
- Nietypowe zapisy plików poza katalogiem uploadu (auditd/EDR/file integrity monitoring).
- Zmiany w plikach konfiguracyjnych, startup scriptach, plikach
.env, artefaktach buildu. - Logi aplikacji i reverse proxy pod kątem podejrzanych nazw plików w multipart (sekwencje
../,%2e%2e%2f, mieszane separatory).
Różnice / porównania z innymi przypadkami (jeśli dotyczy)
Ten incydent dobrze pokazuje różnicę między:
- „podatnością w samej walidacji ścieżki” a
- „podatnością wynikającą z niebezpiecznych domyślnych ustawień API”.
Tutaj kluczowe było to, że bezpieczne zachowanie wymagało od programisty dodatkowej pracy (podania options.name lub sanitacji), a brak tej pracy prowadził do ryzykownego defaultu. Advisory dodatkowo wskazuje, że dokumentacja wcześniej mogła kierować w stronę tej podatnej ścieżki.
To częsty wzorzec w lukach uploadowych: nawet jeśli programista „zapisuje do katalogu uploadów”, wystarczy jedna nieprzemyślana decyzja o budowaniu ścieżki z danych od klienta, aby pojawił się path traversal.
Podsumowanie / kluczowe wnioski
- CVE-2026-21440 (CVSS 9.2) to krytyczna luka typu path traversal w obsłudze uploadów w
@adonisjs/bodyparser, umożliwiająca dowolny zapis/nadpisanie plików na serwerze. - Eksploatacja wymaga osiągalnego endpointu uploadu i podatnego użycia
MultipartFile.move()bez bezpiecznych opcji. - Najlepsza reakcja to natychmiastowa aktualizacja do 10.1.2 (lub 11.0.0-next.6) oraz szybki przegląd miejsc, gdzie aplikacja zapisuje uploady na dysk.
Źródła / bibliografia
- GitHub Security Advisory: AdonisJS Path Traversal in Multipart File Handling (GHSA-gvq6-hvvp-h34h). (GitHub)
- NVD / NIST: CVE-2026-21440. (NVD)
- GitHub Releases:
adonisjs/bodyparserv10.1.2 (opis zmiany domyślnej nazwy pliku nauuid). (GitHub) - The Hacker News: omówienie podatności i warunków eksploatacji (06 stycznia 2026). (The Hacker News)