Aktuální situace: PHP2Shell. Dvě kritické zranitelnosti PHP (CVSS 9.2) umožňují spustit škodlivý kód bez přihlášení. Záplaty od 21. 10. 2026.Co nyní udělat →

Least Privilege: oprávnění uživatele webserveru

Vložený kód běží s právy uživatele webserveru. Co tento účet smí, rozhoduje o tom, jak daleko se útočník dostane. Takto omezíte shell, sudo, cron, databázi a souborový systém na nezbytné minimum.

Stav 5 min čteníHardening a konfigurace

Stručně: Uživatel webserveru, pod kterým běží PHP, by měl podle principu nejmenších oprávnění (Least Privilege) číst jen to, co web potřebuje, a zapisovat jen tam, kam ukládá data. Nemá přihlašovací shell, práva sudo, vlastní cronjoby ani klíče SSH a jeho účet v databázi smí data jen číst a měnit. Volby systemd jako ProtectSystem a PrivateTmp PHP-FPM navíc omezují.

Otázka po průniku: co smí tento proces?

U PHP2Shell jde o spuštění škodlivého kódu na dálku bez přihlášení. Pokud se to podaří, kód neběží v prázdnu, ale pod konkrétním uživatelem: uživatelem procesu PHP. Vše, co tento uživatel smí, smí od té chvíle i útočník.

Na mnoha serverech je to překvapivě hodně. Uživatel vlastní veškerý programový kód, má shell, může zakládat vlastní cronjoby a databázový účet aplikace má všechna práva ke všem databázím. Pro útočníka je to ideální výchozí pozice, aby se na serveru trvale usadil.

Jak správně přidělit práva k souborům a složkám, popisuje příručka Oprávnění k souborům na webserveru. Tento článek se zaměřuje na samotný účet: přihlášení, zvláštní práva, plánované úlohy, databázi a hranice, které vymezuje systemd.

Inventura: kdo je uživatel webserveru?

Nejprve zjistěte, kteří uživatelé se vůbec podílejí. U PHP-FPM určuje každý pool pomocí user a group, pod kým běží jeho workery. U mod_php běží PHP jako uživatel Apache. Jak spolupracují master a workery u PHP-FPM, vysvětluje stránka PHP-FPM vysvětleno: správce procesů, pooly a workeři. Následující příkazy jen čtou:

# Pod jakými uživateli běží webserver a PHP?
ps -eo user,group,cmd | grep -E "[p]hp-fpm|[n]ginx|[a]pache2|[h]ttpd" | sort | uniq -c
# Údaje o účtu: domovský adresář a shell (uživatele upravte)
getent passwd www-data
# Má uživatel práva sudo?
sudo -l -U www-data
# Vlastní cronjoby?
sudo crontab -l -u www-data
# Klíče SSH v domovském adresáři (u Debianu/Ubuntu je to /var/www)
sudo ls -la /var/www/.ssh 2>/dev/null

Výsledky si poznamenejte pro každého uživatele poolu. Pokud všechny weby běží pod stejným uživatelem, je to první bod na seznamu; jak je oddělit, popisuje článek Izolace poolů PHP-FPM pro každý web.

Práva uživatele webserveru: co účet nepotřebuje

Následující přehled ukazuje, co uživatel webserveru typicky nepotřebuje a jak mu to odebrat.

Právo Proč je nebezpečné Doporučení
Přihlašovací shell Je možné přihlášení a interaktivní používání Shell /usr/sbin/nologin
Záznamy sudo Cesta k právům root žádné záznamy, ani pro jednotlivé příkazy
Vlastní crontab trvalá zadní vrátka, která přežijí každý restart žádný, omezit pomocí /etc/cron.allow
Klíče SSH Přihlášení zvenčí žádné authorized_keys
Vlastnictví programového kódu Kód lze měnit Vlastníkem je uživatel pro nasazování
Práva zápisu mimo datové složky Ukládání škodlivého kódu jen uploady, cache, temp
Plná práva k databázi Databáze jiných aplikací, přístup k souborům přes databázi jen vlastní databáze, jen datová práva

Shell nastavíte příkazem usermod -s /usr/sbin/nologin www-data. Pro cron platí: pokud existuje /etc/cron.allow, smějí zakládat vlastní cronjoby jen v něm uvedení uživatelé. Nově založené cronjoby nebo neznámé klíče SSH jsou typickým znamením, že se někdo v systému uchytil. Zvlášť výrazné varovné znamení popisuje článek Varovné znamení: webserver spouští shell.

Databáze: omezte práva na nezbytné

Databázový účet webu je fakticky druhým uživatelem webserveru. Jeho přístupové údaje leží v konfiguračním souboru aplikace a vložený kód je může přečíst. Proto by měl smět jen to, co aplikace v provozu potřebuje.

-- Příklad MySQL/MariaDB: vlastní účet pro každý web, jen datová práva
CREATE USER 'seite1'@'localhost' IDENTIFIED BY 'hier-ein-langes-Zufallspasswort';
GRANT SELECT, INSERT, UPDATE, DELETE ON seite1.* TO 'seite1'@'localhost';
-- Zkontrolovat práva
SHOW GRANTS FOR 'seite1'@'localhost';

Práva jako FILE, SUPER nebo GRANT OPTION a přístup k *.* aplikační účet nepotřebuje. Mnoho CMS potřebuje pro aktualizace navíc CREATE, ALTER, INDEX a DROP. Čistší je samostatný účet pro aktualizace a migrace, který se používá jen při údržbě. Požadavky ověřte v dokumentaci výrobce.

PHP-FPM navíc omezit pomocí systemd

systemd může službu omezit v jejím pohledu na systém. Pro PHP-FPM se obzvlášť hodí některé volby z dokumentace systemd. Působí i na master proces, který startuje jako root.

# sudo systemctl edit php8.3-fpm
[Service]
# /usr, /boot a /etc jen pro čtení
ProtectSystem=full
# /home, /root a /run/user neviditelné
ProtectHome=true
# vlastní /tmp a /var/tmp jen pro tuto službu
PrivateTmp=true
# žádné rozšíření práv přes setuid nebo capabilities souborů
NoNewPrivileges=true

Tyto volby otestujte před nasazením do ostrého provozu. Pokud leží weby pod /home, ProtectHome=true přístup zablokuje. NoNewPrivileges=true může rušit programy, které PHP volá a které při startu mění svá skupinová práva, například některé lokální poštovní programy pro funkci PHP mail(). Postupujte proto po krocích:

  1. Přidejte jednu volbu, restartujte službu, zkontrolujte systemctl status php8.3-fpm.
  2. Otestujte klíčové funkce webu: přihlášení, formuláře, odesílání pošty, uploady, cronjoby aplikace.
  3. Vyhodnoťte chybový log PHP-FPM a aplikace.
  4. Teprve pak přidejte další volbu.

Nakonec socket: Podle příručky PHP dostává ve výchozím stavu práva 0660 pro uživatele a skupinu poolu. Nastavte listen.owner a listen.group tak, aby se mohl připojit jen webserver, ne každý lokální uživatel.

Tip

Minimální práva jsou postoj, ne jednorázový projekt. Inventuru z tohoto článku opakujte po každé přestavbě a po každém novém webu, protože nové služby často přicházejí s velkorysými výchozími právy.

Závěr: útočník zdědí to, co povolíte

Least Privilege zní jako teorie, ale je to velmi praktická otázka: co může udělat ten, kdo spouští kód jako uživatel webserveru? Na serveru se shellem, záznamem sudo, vlastním crontabem a databázovým účtem se všemi právy zní odpověď: téměř vše. Na omezeném serveru zůstane spíše u incidentu v jednom webu, který lze rozpoznat a vyčistit.

Změna nevyžaduje žádný nový software, jen pečlivou inventuru a postupné testy. Začněte body, které téměř nic nerozbijí, tedy shellem, sudo a klíči SSH, a poté postupujte k právům k databázi a volbám systemd.

Jak konkrétně pomáhá PHP SOS?

  • Kontrola účtů: Pro každý pool a webserver zaznamenáme uživatele, shell, záznamy sudo, cronjoby, klíče SSH a práva k databázi.
  • Snížení práv: Odebereme, co není potřeba, a oddělíme účty pro nasazování, běh a údržbu.
  • Omezení služeb: Ochranné volby systemd nastavujeme postupně a po každém kroku web testujeme.
  • Udržení v čase: V rámci hardeningu serveru zdokumentujeme koncepci oprávnění pro budoucí změny.

Časté dotazy

Pod jakým uživatelem běží PHP na mém serveru?

Záleží na provozním režimu. U mod_php běží PHP jako uživatel Apache, například www-data nebo apache. U PHP-FPM určuje uživatele každý pool pomocí user a group; hlavní proces (master) většinou běží jako root, workery jako uživatel poolu. Příkaz ps to ukáže rychle.

Potřebuje uživatel webserveru přihlašovací shell?

Ne. Nginx, Apache ani PHP-FPM nepotřebují pro tohoto uživatele interaktivní přihlášení. Shell jako /usr/sbin/nologin brání tomu, aby se někdo pod tímto účtem přihlásil. Nasazování probíhá pod samostatným uživatelem.

Proč www-data nedávat žádná práva sudo, ani pro jediný příkaz?

Protože vložený kód zdědí přesně tato práva. I zdánlivě neškodný příkaz může být při chybném povolení cestou k právům root. Úlohy, které vyžadují vyšší oprávnění, patří do samostatných služeb nebo postupů mimo webserver.

Pomůže to proti PHP2Shell?

Zranitelnost to neuzavře, k tomu je potřeba aktualizace PHP a restart všech workerů. Minimální práva ale omezují, co může útočník po úspěšném zneužití udělat: měnit soubory, uchytit se v systému, dosáhnout na jiné weby.

Zdroje

Okamžitý kontakt

Každá hodina se počítá. Napište nám hned.

Stručně popište systém, verzi PHP a pozorování. Ozveme se, vyjasníme situaci a budeme pracovat na dálku, dokud nebude incident uzavřen a zdokumentován.

Okamžitá pomoc