wgranie dowolnego pliku (arbitrary file upload)
| Po angielsku | arbitrary file upload |
|---|---|
| Którą formą pisać | obie formy Obie formy są w obiegu. Przy pierwszym wystąpieniu pisz „polski termin (english term)”, dalej sam polski. |
| Inne formy | nieograniczone wgrywanie plików · przesyłanie plików · upload plików |
| Kategoria | Podatności i klasy błędów |
Wgranie dowolnego pliku (arbitrary file upload) to podatność, w której aplikacja przyjmuje plik bez poprawnego sprawdzenia jego typu i zawartości, co pozwala umieścić na serwerze skrypt, który serwer potem wykona. MITRE katalogizuje tę słabość jako CWE-434: produkt pozwala wgrać lub przesłać pliki niebezpiecznego typu, które są automatycznie przetwarzane w jego środowisku [1]. MITRE uznaje popularną nazwę „unrestricted file upload” za nieprecyzyjną, bo może oznaczać także brak limitu rozmiaru lub liczby plików [1]. W zestawieniu CWE Top 25 za 2024 rok CWE-434 zajęła dziesiąte miejsce [3].
Jak działa
Sekurak zauważa, że wgrywanie plików należy do najczęściej spotykanych funkcji aplikacji internetowych [4]. Formularz przyjmuje awatar, załącznik do zgłoszenia albo CV. Jeśli serwer zapisze plik pod nazwą podaną przez użytkownika w katalogu dostępnym z sieci, a serwer WWW wykonuje w tym katalogu PHP, każdy plik z rozszerzeniem .php stanie się programem. Sekurak opisuje scenariusz, w którym użytkownik wgrywa plik hack.php, a potem otwiera go pod adresem katalogu uploads, co daje zdalne wykonanie kodu [4].
MITRE podaje przykład skryptu PHP, który zapisuje przesłany plik bez sprawdzenia typu; atakujący wgrywa plik z jednym wywołaniem funkcji system() i wykonuje polecenia przez parametr w adresie [1]. Taki plik to najprostszy webshell.
Techniki obejścia
Filtry oparte na jednym sprawdzeniu łatwo obejść. OWASP ostrzega, że nagłówek Content-Type można sfałszować, i wymienia podwójne rozszerzenia, bajty zerowe oraz zmianę wielkości liter [2].
| Technika | Przykład | Co wykorzystuje |
|---|---|---|
| Fałszywy typ MIME | Content-Type: image/jpeg dla skryptu [2] | zaufanie do nagłówka klienta |
| Podwójne rozszerzenie | plik.php.gif, test.php.jpg [1] [4] | konfigurację obsługi rozszerzeń w Apache |
| Bajt zerowy | .php%00.jpg [2] | ucinanie nazwy w starszych bibliotekach |
| Wielkość liter | .ASPX zamiast .aspx [4] | system plików bez rozróżniania liter |
Własny .htaccess | dyrektywa AddHandler dla .jpeg [4] | możliwość nadpisania konfiguracji katalogu |
MITRE opisuje błąd CVE-2006-4558, w którym nazwa filename.php.gif pozostawała wykonywalnym skryptem PHP mimo pozornego rozszerzenia obrazka [1]. Wgrywanie łączy się też z path traversal: jeśli nazwa pliku zawiera sekwencję ../, zapis może trafić poza katalog uploads.
W WordPressie
Na stronie WordPress wgrywanie plików przez bibliotekę mediów wymaga zdolności upload_files, którą domyślnie mają administrator, redaktor i autor, ale nie współpracownik ani subskrybent [6]. Zdolność unfiltered_upload, pozwalająca wgrywać pliki dowolnego typu, nie przysługuje domyślnie żadnej roli, nawet superadministratorowi, i wymaga zdefiniowania stałej ALLOW_UNFILTERED_UPLOADS [6]. Szczegóły opisuje hasło role i uprawnienia użytkowników.
Rdzeń sprawdza typ pliku funkcją wp_check_filetype_and_ext(), która próbuje ustalić rzeczywisty typ pliku i przepuszcza tylko typy MIME dozwolone na stronie [5]. Dla obrazów korzysta z getimagesize(), a dla innych plików z rozszerzenia fileinfo PHP, jeśli jest dostępne [5].
Większość podatności tego typu dotyczy więc nie biblioteki mediów, lecz wtyczek, które obsługują wgrywanie po swojemu: formularzy kontaktowych, importerów, kreatorów motywów, modułów zgłoszeń; zob. podatność we wtyczce. Typowy błąd to akcja AJAX lub trasa REST, która wywołuje move_uploaded_file() z nazwą od użytkownika, bez sprawdzenia uprawnień i typu. Jeśli akcja jest dostępna dla niezalogowanych, powstaje podatność wykorzystywana bez uwierzytelnienia.
Drugą warstwą jest blokada wykonywania PHP w katalogu uploads, realizowana w konfiguracji serwera lub przez zabezpieczenia w .htaccess. Nie usuwa ona błędu we wtyczce, ale sprawia, że wgrany skrypt nie zostanie uruchomiony.
Zagrożenia i skutki
Podstawowym skutkiem jest zdalne wykonanie kodu (remote code execution). MITRE zaznacza, że kod jest wykonywany, jeśli wgrany plik zostanie zinterpretowany jako program, zwłaszcza przy rozszerzeniach takich jak .php i .asp, które serwer wykonuje automatycznie [1]. Wgrany skrypt zwykle staje się tylną furtką, przez którą atakujący wraca na stronę po usunięciu pierwotnej luki. Z serwera może potem podmieniać treść, instalować złośliwe oprogramowanie i czytać pliki konfiguracyjne. Na hostingu współdzielonym skutki zależą od tego, czy konta klientów są od siebie odizolowane.
Jak się bronić
MITRE i OWASP zalecają podobny zestaw środków [1] [2]:
- nadawać plikom nowe, generowane przez aplikację nazwy zamiast nazw od użytkownika [1] [2];
- dopuszczać tylko krótką listę rozszerzeń potrzebnych w danej funkcji i sprawdzać je bez względu na wielkość liter [1];
- sprawdzać typ po stronie serwera i nie ufać nagłówkowi
Content-Type[1] [2]; - przechowywać pliki na osobnym serwerze albo poza katalogiem głównym serwisu [1] [2];
- pozwalać na wgrywanie tylko uprawnionym użytkownikom, ustalić limit rozmiaru i chronić formularz przed CSRF (Cross-Site Request Forgery) [2].
Sekurak dodaje nagłówki Content-Disposition: attachment i X-Content-Type-Options: nosniff oraz, jeśli to możliwe, osobną domenę dla wgrywanych plików [4]. W WordPressie wgrywanie we własnym kodzie powinno przechodzić przez funkcje rdzenia, które korzystają z wp_check_filetype_and_ext(), a sanityzacja nazwy pliku jest tylko jednym z elementów. Wgrane skrypty pomaga wykryć monitorowanie integralności plików.
Historia i przykłady
28 sierpnia 2026 roku CERT Polska ostrzegł przed krytyczną podatnością CVE-2026-65643 w oprogramowaniu do zarządzania hostingiem cPanel/WHM [7]. Pozwalała ona uwierzytelnionemu posiadaczowi konta cPanel z uprawnieniem do dodawania domen utworzyć dowolne pliki na serwerze, co mogło prowadzić do wykonania kodu z uprawnieniami użytkownika root [7]. CERT Polska zalecił niezwłoczną aktualizację [7].
Przypisy
7- [1] CWE-434: Unrestricted Upload of File with Dangerous Type · MITRE
- [2] File Upload Cheat Sheet · OWASP
- [3] 2024 CWE Top 25 Most Dangerous Software Weaknesses · MITRE
- [4] Bezpieczeństwo aplikacji webowych: podatności w mechanizmach uploadu · Sekurak
- [5] wp_check_filetype_and_ext() — Function Reference · WordPress.org
- [6] Roles and Capabilities · WordPress.org
- [7] Krytyczna podatność w oprogramowaniu cPanel/WHM · CERT Polska
Hasła w tym artykule
16- podatność
- CWE
- webshell
- path traversal
- role i uprawnienia użytkowników
- podatność we wtyczce
- podatność wykorzystywana bez uwierzytelnienia
- blokada wykonywania PHP w katalogu uploads
- zabezpieczenia w .htaccess
- zdalne wykonanie kodu (RCE)
- tylna furtka
- złośliwe oprogramowanie
- hosting współdzielony
- CSRF (Cross-Site Request Forgery)
- sanityzacja danych wejściowych
- monitorowanie integralności plików
Linkują tutaj
15- ransomware
- ładunek
- podatność we wtyczce
- webshell
- bug bounty
- path traversal
- blokada wykonywania PHP w katalogu uploads
- deserializacja niezaufanych danych (insecure deserialization)
- podatność wykorzystywana bez uwierzytelnienia
- RFI (Remote File Inclusion)
- race condition
- zdalne wykonanie kodu (RCE)
- LFI (Local File Inclusion)
- usunięcie dowolnego pliku
- CERT Polska / CSIRT NASK, CSIRT GOV, CSIRT MON