Röviden: A PHP-végrehajtás feltöltésekben való tiltásához először állapítsa meg az összes mappát, amelybe a PHP írhat, majd mindegyikben zárolja a szkriptek végrehajtását a szerverkonfigurációban, nem a .htaccess-szel. Az Nginxben a zárolásnak az általános PHP-blokk előtt kell érvényesülnie, az Apache-ban az AllowOverride None értékű VirtualHostba tartozik. A security.limit_extensions = .php az FPM-poolban és egy ártalmatlan fájllal végzett teszt zárja le a munkát.
Miért éppen most számítanak a feltöltési mappák
Egy kritikus rés, például a PHP2Shell után a támadók ritkán akarnak csak egyszer kódot futtatni. Vissza akarnak térni, akkor is, ha a szervert később kijavítják. Ennek legegyszerűbb útja egy webshell: egy kis PHP-fájl, amelyet egy írható mappában helyeznek el, és később a böngészőn keresztül hívnak meg.
Egy javítás nem távolítja el az ilyen fájlt. Aki 2026. október 20-tól javítatlanul volt online, annak ezért nem elég frissítenie, hanem ellenőriznie is kell, hogy hol vannak új PHP-fájlok, és a jövőben meg kell akadályoznia, hogy végrehajtsák őket. Hogyan értelmezze a lelőhelyeket, azt a PHP-fájlok a feltöltési mappában: a lelőhelyek helyes értelmezése írja le.
A végrehajtási zárolás a második feltételnél támad. Nem akadályozza meg, hogy egy fájlt elhelyezzenek, hanem azt, hogy a szerver programként kezelje.
Először a leltár: hol írhat a PHP?
A legtöbb útmutató csak a feltöltési mappát említi. A gyakorlatban egy PHP-alkalmazás sokkal több helyre ír. Mindegyik, amely a webszerveren keresztül elérhető, zárolásra szorul.
| Mappatípus | Tipikus tartalom | Miért írható |
|---|---|---|
| Feltöltések, média | képek, PDF-ek, mellékletek | a felhasználók és a szerkesztőség fájlokat töltenek fel |
| Gyorsítótár | előállított oldalak, előnézeti képek | az alkalmazás gyorsítja a kiszolgálást |
| Temp, import, export | CSV-fájlok, köztes állapotok | felületek és adatcsere |
| Mentések a webrootban | .zip, .sql |
a bővítmények „helyben” mentenek |
| Naplók a webrootban | hiba- és debug-naplók | hibásan konfigurált alkalmazások |
Hogy a szerverén mely mappák ezek, azt a futtatási felhasználó jogaival végzett keresés mutatja meg. Nem módosít semmit:
# Az összes mappa a /var/www alatt, amelybe a PHP-felhasználó írhat
# (a felhasználót igazítsa: www-data, nginx, apache vagy saját pool-felhasználó)
sudo -u www-data find /var/www -type d -writable 2>/dev/null | sort
# Vannak már PHP-fájlok ezekben a mappákban?
sudo -u www-data find /var/www -type d -writable -print0 2>/dev/null \
| xargs -0 -I{} find {} -maxdepth 1 -type f -iname "*.ph*" 2>/dev/null
Ha az első keresés az egész webrootot visszaadja, a programkód a futtatási felhasználó tulajdonában van. Ezt előtte módosítsa, ahogyan a Fájljogosultságok a webszerveren útmutató leírja. Különben nincs olyan mappa, amelyet ne kellene zárolni.
PHP-végrehajtás tiltása a feltöltésekben: Nginx
Az Nginxnél a sorrend dönt. Az Nginx dokumentációja szerint a reguláris kifejezéseket a konfigurációs fájl sorrendjében vizsgálja, és az első találat nyer. Ha az általános location ~ \.php$ blokk a zárolás előtt áll, a fájlt végrehajtják. Egy ^~ nélküli egyszerű prefix-location ugyanezen okból nem véd.
Biztonságos egy reguláris kifejezés az összes zárolt mappára, amely a PHP-blokk előtt áll. A ritkán használt végződéseket is lefedi:
server {
# ... alapkonfiguráció ...
# 1. Zárolás az írható mappákra, a PHP-blokk ELŐTT kell állnia
location ~* ^/(uploads|media|cache|tmp|export)/.*\.(php\d?|phtml|phar|pht|phps)$ {
deny all;
}
# 2. Általános PHP-blokk: csak létező fájlokat adni át
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/seite1.sock;
}
}
A mappaneveket igazítsa a leltárához. Egyetlen belépési ponttal rendelkező alkalmazásoknál az engedélyezési listán keresztüli út még erősebb; a mintát az Az Nginx biztonságos konfigurálása PHP-hez mutatja.
Apache és PHP-FPM: a zárolás a helyes helyen
Az Apache-ban a zárolás a szerverkonfigurációba vagy a VirtualHostba való. Egy .htaccess a feltöltési mappában alkalmatlan, mert bárki módosíthatja, aki ott írhat. Az egész webrootra ezért az AllowOverride None érvényes. Az Apache dokumentációja szerint az AllowOverride csak reguláris kifejezések nélküli <Directory> blokkokban megengedett, tehát azt a webrootnál állítsa be, a zárolást pedig <DirectoryMatch>-csel alatta:
<Directory /var/www/seite1/public>
AllowOverride None
Require all granted
</Directory>
<DirectoryMatch "^/var/www/seite1/public/(uploads|media|cache|tmp|export)/">
<FilesMatch "\.(php\d?|phtml|phar|pht|phps)$">
Require all denied
</FilesMatch>
</DirectoryMatch>
Ha még mod_php fut, ugyanabban a blokkban egészítse ki a php_admin_flag engine off direktívával. PHP-FPM esetén egy második korlát hat a poolban: a security.limit_extensions határozza meg, mely végződéseket hajtja végre egyáltalán az FPM. A PHP kézikönyve szerint az alapértelmezés a .php .phar; a .php-re való korlátozás ajánlott.
; a poolban, pl. /etc/php/8.3/fpm/pool.d/seite1.conf
security.limit_extensions = .php
Tesztelés ártalmatlan fájllal
Hogy a zárolás hat-e, azt csak egy teszt mutatja meg. Helyezzen minden zárolt mappába rövid időre egy fájlt, amely csak egy szöveget ír ki, hívja meg a domainen keresztül, és utána törölje.
- A konfiguráció ellenőrzése:
nginx -tilletveapachectl configtest, majd újratöltés. - A tesztfájl létrehozása, például
uploads/sperrtest.php, a tartalma<?php echo 'ausgefuehrt';. - Meghívni a
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/uploads/sperrtest.phpparanccsal. Az elvárt eredmény403. - Ha ehelyett
200és az „ausgefuehrt” szöveg jelenik meg, a zárolás nem hat. Ellenőrizze a konfigurációt és a sorrendet. - Törölje a tesztfájlt, és ismételje meg a tesztet minden mappára és minden weboldalra.
Ha a leltárnál már ismeretlen PHP-fájlokat talál írható mappákban, ne töröljön semmit elhamarkodottan. Először mentse az állapotot és a naplókat, mert ezek a fájlok bizonyítékok. Hogyan járjon el ezután, azt a Webshellek felismerése és eltávolítása írja le.
Hogyan építik fel biztonságosan a feltöltési funkciókat a kódban, típusellenőrzéssel és a webrooton kívüli tárolással, azt a Fájlfeltöltés biztonságos megvalósítása PHP-ban útmutató tartalmazza.
Összegzés: írni lehet, végrehajtani nem
Az írható mappákban lévő végrehajtási zárolás a tartós hátsó ajtók elleni egyik leghatékonyabb egyedi intézkedés. Néhány sor konfigurációba kerül, és tiszta felépítésű alkalmazásoknál semmit sem tör meg. Három dolog a döntő: teljes leltár a csak nyilvánvaló feltöltési mappa helyett, a helyes sorrend az Nginxben, illetve a helyes szint az Apache-ban, és egy valódi teszt ártalmatlan fájllal.
Kiegészítve a programkód elkülönített tulajdonosaival, a poolban lévő security.limit_extensions-szel és az új PHP-fájlok rendszeres keresésével olyan állapot jön létre, amelyben egy elhelyezett fájl bosszantó ugyan, de alig használható. Ez sem a frissítést, sem a nyomkeresést nem pótolja, de elvesz a támadóktól egyet a legfontosabb eszközeik közül.
Hogyan segít konkrétan a PHP SOS?
- Leltár: Weboldalanként megállapítjuk az összes írható mappát, és ellenőrizzük őket meglévő PHP-fájlok után.
- Zárolások beállítása: A végrehajtási zárolásokat beírjuk az Nginxbe, az Apache-ba és a PHP-FPM-be, a helyes sorrendben és
.htaccess-függőség nélkül. - Tesztelés: Minden zárolást ártalmatlan fájllal ellenőrzünk, és dokumentáljuk az eredményt.
- Tisztítás: Lelet esetén átvesszük a nyomrögzítést és a kártevő-eltávolítást.
Gyakori kérdések
Elég egy .htaccess a feltöltési mappában a PHP tiltásához?
Nem megbízhatóan. Aki a mappába írhat, a .htaccess fájlt is módosíthatja vagy lecserélheti. A zárolás a szerverkonfigurációba vagy a VirtualHostba való, a webrootra pedig az AllowOverride None legyen érvényes.
Mely mappákat kell zárolnom?
Mindazokat, amelyekbe a PHP-felhasználó írhat, és amelyek a webszerveren keresztül elérhetők. A feltöltési mappák mellett ezek gyakran a gyorsítótár-, temp-, import-, export- és mentési könyvtárak. Futtatási felhasználóként végzett kereséssel állapítsa meg őket.
Megbontja a zárolás a weboldalamat?
Általában nem, mert a feltöltési és gyorsítótár-mappákban tiszta alkalmazásoknál nincsenek közvetlenül meghívott szkriptek. Egyes bővítmények azonban mégis PHP-fájlokat helyeznek el ott. Ezért az átállás után tesztelje a legfontosabb funkciókat.
Véd a zárolás a PHP2Shell ellen?
Nem. A PHP2Shell a PHP-értelmezőben lévő rés, amelyet csak a frissítés és az összes worker újraindítása zár le. A zárolás viszont megakadályozza, hogy egy elhelyezett fájlt később a böngészőn keresztül meghívjanak és tartós hátsó ajtóként használjanak.