Aktualna sytuacja: PHP2Shell. Dwie krytyczne luki w PHP (CVSS 9,2) umożliwiają wykonanie złośliwego kodu bez logowania. Poprawki od 21.10.2026.Co należy teraz zrobić →

Least Privilege: uprawnienia użytkownika serwera WWW

Wstrzyknięty kod działa z uprawnieniami użytkownika serwera WWW. To, na co pozwala to konto, decyduje o tym, jak daleko zajdzie atakujący. Jak ograniczyć powłokę, sudo, cron, bazę danych i system plików do tego, co niezbędne.

Stan 5 min czytaniaUtwardzanie i konfiguracja

Krótko: Użytkownik serwera WWW, pod którym działa PHP, powinien zgodnie z zasadą minimalnych uprawnień (Least Privilege) czytać tylko to, czego strona potrzebuje, i zapisywać tylko tam, gdzie strona składa dane. Nie ma powłoki logowania, uprawnień sudo, własnych zadań cron ani kluczy SSH, a jego konto bazodanowe może wyłącznie odczytywać i zmieniać dane. Opcje systemd, takie jak ProtectSystem i PrivateTmp, dodatkowo ograniczają PHP-FPM.

Pytanie po włamaniu: co wolno temu procesowi?

PHP2Shell dotyczy zdalnego wykonania złośliwego kodu bez logowania. Jeśli się powiedzie, kod nie działa w próżni, lecz jako konkretny użytkownik: użytkownik procesu PHP. Wszystko, co temu użytkownikowi wolno, od tej chwili wolno także atakującemu.

Na wielu serwerach jest tego zaskakująco dużo. Użytkownik jest właścicielem całego kodu programu, ma powłokę, może zakładać własne zadania cron, a konto bazodanowe aplikacji ma wszystkie uprawnienia do wszystkich baz. Dla atakującego to idealna sytuacja wyjściowa, aby zadomowić się na stałe.

Jak prawidłowo nadawać uprawnienia do plików i katalogów, opisuje poradnik Uprawnienia do plików na serwerze WWW. Ten wpis skupia się na samym koncie: logowaniu, uprawnieniach specjalnych, zadaniach zaplanowanych, bazie danych i granicach, które wyznacza systemd.

Inwentaryzacja: kim jest użytkownik serwera WWW?

Najpierw ustal, którzy użytkownicy w ogóle są zaangażowani. W PHP-FPM każda pula określa za pomocą user i group, pod kim działają jej procesy robocze. W przypadku mod_php PHP działa jako użytkownik Apache. Jak współpracują proces główny i procesy robocze w PHP-FPM, wyjaśnia artykuł PHP-FPM wyjaśnione: menedżer procesów, pule i procesy robocze. Poniższe polecenia tylko odczytują dane:

# Pod jakimi użytkownikami działają serwer WWW i PHP?
ps -eo user,group,cmd | grep -E "[p]hp-fpm|[n]ginx|[a]pache2|[h]ttpd" | sort | uniq -c
# Dane konta: katalog domowy i powłoka (dostosować użytkownika)
getent passwd www-data
# Czy użytkownik ma uprawnienia sudo?
sudo -l -U www-data
# Własne zadania cron?
sudo crontab -l -u www-data
# Klucze SSH w katalogu domowym (w Debianie/Ubuntu jest to /var/www)
sudo ls -la /var/www/.ssh 2>/dev/null

Zapisz wyniki dla każdego użytkownika puli. Jeśli wszystkie strony działają pod tym samym użytkownikiem, jest to pierwszy punkt na liście; jak to rozdzielić, opisuje wpis Izolowanie pul PHP-FPM dla każdej strony.

Uprawnienia użytkownika serwera WWW: czego konto nie potrzebuje

Poniższe zestawienie pokazuje, czego użytkownik serwera WWW zazwyczaj nie potrzebuje i jak mu to odebrać.

Uprawnienie Dlaczego jest niebezpieczne Zalecenie
Powłoka logowania Możliwe logowanie i interaktywne użycie Powłoka /usr/sbin/nologin
Wpisy sudo Droga do uprawnień roota brak wpisów, także dla pojedynczych poleceń
Własna crontab trwała furtka, która przetrwa każdy restart brak, ograniczyć przez /etc/cron.allow
Klucze SSH Logowanie z zewnątrz brak authorized_keys
Własność kodu programu Kod może zostać zmieniony Właścicielem jest użytkownik wdrożeniowy
Uprawnienia zapisu poza katalogami z danymi Umieszczenie złośliwego kodu tylko uploady, cache, temp
Pełne uprawnienia do bazy danych Bazy innych aplikacji, dostęp do plików przez bazę tylko własna baza, tylko prawa do danych

Powłokę ustawiasz poleceniem usermod -s /usr/sbin/nologin www-data. Dla crona obowiązuje zasada: jeśli istnieje /etc/cron.allow, własne zadania cron mogą zakładać tylko wymienieni tam użytkownicy. Nowo utworzone zadania cron lub nieznane klucze SSH to typowy znak, że ktoś zadomowił się w systemie. Szczególnie wyraźne ostrzeżenie opisuje wpis Sygnał ostrzegawczy: serwer WWW uruchamia powłokę.

Baza danych: ograniczyć uprawnienia do niezbędnych

Konto bazodanowe strony to faktycznie drugi użytkownik serwera WWW. Jego dane dostępowe znajdują się w pliku konfiguracyjnym aplikacji i są dostępne do odczytu dla wstrzykniętego kodu. Dlatego powinno mieć tylko te uprawnienia, których aplikacja potrzebuje w działaniu.

-- Przykład MySQL/MariaDB: osobne konto dla każdej strony, tylko prawa do danych
CREATE USER 'seite1'@'localhost' IDENTIFIED BY 'hier-ein-langes-Zufallspasswort';
GRANT SELECT, INSERT, UPDATE, DELETE ON seite1.* TO 'seite1'@'localhost';
-- Sprawdzić uprawnienia
SHOW GRANTS FOR 'seite1'@'localhost';

Uprawnień takich jak FILE, SUPER czy GRANT OPTION oraz dostępu do *.* konto aplikacji nie potrzebuje. Wiele systemów CMS wymaga do aktualizacji dodatkowo CREATE, ALTER, INDEX i DROP. Czystszym rozwiązaniem jest osobne konto do aktualizacji i migracji, używane tylko podczas prac serwisowych. Wymagania sprawdź w dokumentacji producenta.

Dodatkowe ograniczenie PHP-FPM za pomocą systemd

systemd może ograniczyć widok usługi na system. Dla PHP-FPM szczególnie nadaje się kilka opcji z dokumentacji systemd. Działają one także na proces główny, który startuje jako root.

# sudo systemctl edit php8.3-fpm
[Service]
# /usr, /boot i /etc tylko do odczytu
ProtectSystem=full
# /home, /root i /run/user niewidoczne
ProtectHome=true
# własny /tmp i /var/tmp tylko dla tej usługi
PrivateTmp=true
# brak rozszerzania uprawnień przez setuid lub capabilities plików
NoNewPrivileges=true

Przetestuj te opcje przed użyciem produkcyjnym. Jeśli strony znajdują się w /home, ProtectHome=true uniemożliwia dostęp. NoNewPrivileges=true może zakłócać programy wywoływane przez PHP, które przy starcie zmieniają uprawnienia grupowe, na przykład niektóre lokalne programy pocztowe dla funkcji PHP mail(). Dlatego działaj krok po kroku:

  1. Dodaj jedną opcję, zrestartuj usługę, sprawdź systemctl status php8.3-fpm.
  2. Przetestuj podstawowe funkcje strony: logowanie, formularze, wysyłkę poczty, uploady, zadania cron aplikacji.
  3. Przeanalizuj log błędów PHP-FPM i aplikacji.
  4. Dopiero potem dodaj kolejną opcję.

Na koniec gniazdo: według podręcznika PHP domyślnie otrzymuje ono uprawnienia 0660 dla użytkownika i grupy puli. Ustaw listen.owner i listen.group tak, aby połączyć się mógł tylko serwer WWW, a nie każdy użytkownik lokalny.

Wskazówka

Minimalne uprawnienia to postawa, a nie jednorazowy projekt. Powtórz inwentaryzację z tego wpisu po każdej przebudowie i po każdej nowej stronie, ponieważ nowe usługi często mają hojne uprawnienia domyślne.

Podsumowanie: atakujący dziedziczy to, na co pozwolisz

Least Privilege brzmi jak teoria, ale to bardzo praktyczne pytanie: co może zrobić ktoś, kto wykonuje kod jako użytkownik serwera WWW? Na serwerze z powłoką, wpisem sudo, własną crontab i kontem bazodanowym ze wszystkimi uprawnieniami odpowiedź brzmi: prawie wszystko. Na serwerze o ograniczonych uprawnieniach incydent zwykle pozostaje w obrębie jednej strony, którą można wykryć i oczyścić.

Zmiana nie wymaga nowego oprogramowania, a jedynie starannej inwentaryzacji i testów krok po kroku. Zacznij od punktów, które prawie niczego nie mogą zepsuć, czyli powłoki, sudo i kluczy SSH, a następnie przejdź do uprawnień bazy danych i opcji systemd.

Jak konkretnie pomaga PHP SOS?

  • Kontrola kont: Dla każdej puli i serwera WWW zestawiamy użytkownika, powłokę, wpisy sudo, zadania cron, klucze SSH i uprawnienia do bazy danych.
  • Ograniczenie uprawnień: Odbieramy to, co nie jest potrzebne, i rozdzielamy konta wdrożeniowe, uruchomieniowe i serwisowe.
  • Ograniczenie usług: Opcje ochronne systemd wdrażamy krok po kroku i po każdym kroku testujemy stronę.
  • Utrzymanie na stałe: W ramach utwardzania serwera dokumentujemy koncepcję uprawnień na potrzeby przyszłych zmian.

Częste pytania

Pod jakim użytkownikiem działa PHP na moim serwerze?

Zależy to od trybu pracy. W przypadku mod_php PHP działa jako użytkownik Apache, na przykład www-data lub apache. W PHP-FPM każda pula określa własnego użytkownika za pomocą user i group; proces główny (master) działa zwykle jako root, a procesy robocze (worker) jako użytkownik puli. Polecenie ps szybko to pokazuje.

Czy użytkownik serwera WWW potrzebuje powłoki logowania?

Nie. Ani Nginx, ani Apache, ani PHP-FPM nie wymagają dla tego użytkownika interaktywnego logowania. Powłoka taka jak /usr/sbin/nologin uniemożliwia zalogowanie się na to konto. Wdrożenia przebiegają przez osobnego użytkownika.

Dlaczego www-data nie powinien mieć uprawnień sudo, nawet do jednego polecenia?

Ponieważ wstrzyknięty kod dziedziczy dokładnie te uprawnienia. Nawet pozornie nieszkodliwe polecenie, jeśli zostanie błędnie udostępnione, może prowadzić do uprawnień roota. Zadania wymagające podwyższonych uprawnień należą do oddzielnych usług lub procesów poza serwerem WWW.

Czy to pomaga przy PHP2Shell?

Nie zamyka to luki; do tego potrzebna jest aktualizacja PHP i restart wszystkich procesów roboczych. Minimalne uprawnienia ograniczają jednak to, co atakujący może zrobić po udanym wykorzystaniu luki: zmieniać pliki, zadomowić się w systemie, dotrzeć do innych stron.

Źródła

Kontakt natychmiast

Liczy się każda godzina. Proszę napisać do nas teraz.

Proszę krótko opisać system, wersję PHP i obserwacje. Skontaktujemy się z Państwem, ustalimy sytuację i będziemy pracować zdalnie, aż incydent zostanie zamknięty i udokumentowany.

Natychmiastowa pomoc