# Zákaz vykonávania PHP v priečinkoch s uploadmi

> Zákaz vykonávania PHP v uploadoch: nájdite zapisovateľné priečinky, správne nastavte blokovanie v Nginx, Apache a PHP-FPM a otestujte ho neškodným súborom.

Zdroj: https://phpsos.de/sk/blog/php-in-uploads-verbieten/  
Stav: 25.10.2026  
Poskytovateľ: PHP SOS, Núdzová pomoc pri PHP a bezpečnosť serverov. Okamžitá pomoc cez WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20de%C5%88%2C%20PHP%20SOS%2C%20potrebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20serverom%20s%20PHP.%20Spolo%C4%8Dnos%C5%A5%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručne:** Ak chcete zakázať vykonávanie PHP v uploadoch, najprv zistite všetky priečinky, do ktorých smie PHP zapisovať, a potom v každom z nich zablokujte vykonávanie skriptov v konfigurácii servera, nie cez `.htaccess`. V Nginx musí blokovanie zaberať pred všeobecným blokom PHP, v Apache patrí do VirtualHost s `AllowOverride None`. `security.limit_extensions = .php` v poole FPM a test neškodným súborom prácu uzavrú.

## Prečo práve teraz záleží na priečinkoch s uploadmi

Po kritickej zraniteľnosti ako PHP2Shell útočníci zriedka chcú vykonať kód len raz. Chcú sa vrátiť, aj keď sa server neskôr zaplátuje. Najjednoduchšou cestou je webshell: malý súbor PHP uložený v zapisovateľnom priečinku a neskôr otvorený cez prehliadač.

Záplata takýto súbor neodstráni. Kto bol od 20. októbra 2026 online nezáplatovaný, nemal by preto len aktualizovať, ale aj skontrolovať, či niekde neležia nové súbory PHP, a do budúcna zabrániť ich vykonaniu. Ako nálezy správne vyhodnotiť, opisuje [Súbory PHP v priečinku s uploadmi: správne vyhodnotenie nálezov](https://phpsos.de/sk/blog/php-dateien-im-upload-ordner/).

Blokovanie vykonávania nadväzuje na druhú podmienku. Nebráni tomu, aby sa súbor uložil, ale tomu, aby ho server považoval za program.

## Najprv inventúra: kam smie PHP zapisovať?

Väčšina návodov uvádza len priečinok s uploadmi. V praxi aplikácia PHP zapisuje na oveľa viac miest. Každé z nich, ktoré je dostupné cez webový server, potrebuje blokovanie.

| Typ priečinka | Typický obsah | Prečo zapisovateľný |
|---|---|---|
| Uploady, médiá | obrázky, PDF, prílohy | používatelia a redakcia nahrávajú súbory |
| Cache | vytvorené stránky, náhľady obrázkov | aplikácia zrýchľuje doručovanie |
| Temp, import, export | súbory CSV, medzistavy | rozhrania a výmena údajov |
| Zálohy vo webovom koreni | `.zip`, `.sql` | rozšírenia zálohujú „na mieste“ |
| Protokoly vo webovom koreni | chybové a ladiace protokoly | nesprávne nakonfigurované aplikácie |

Ktoré priečinky to na vašom serveri sú, ukáže hľadanie s právami používateľa behu. Nič nemení:

```bash
# Všetky priečinky pod /var/www, do ktorých smie zapisovať používateľ PHP
# (upraviť používateľa: www-data, nginx, apache alebo vlastný používateľ poolu)
sudo -u www-data find /var/www -type d -writable 2>/dev/null | sort
# Ležia v týchto priečinkoch už súbory PHP?
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
```

Ak prvé hľadanie vráti celý webový koreň, programový kód patrí používateľovi behu. To by ste mali vopred zmeniť, ako opisuje sprievodca [Práva k súborom na webovom serveri](https://phpsos.de/sk/ratgeber/dateirechte-webserver/). Inak neexistuje priečinok, ktorý by sa nemusel blokovať.

## Zákaz vykonávania PHP v uploadoch: Nginx

V Nginx rozhoduje poradie. Podľa dokumentácie Nginx sa regulárne výrazy kontrolujú v poradí konfiguračného súboru a vyhráva prvá zhoda. Ak všeobecný blok `location ~ \.php$` stojí pred vaším blokovaním, súbor sa vykoná. Jednoduchá lokácia s predponou bez `^~` z rovnakého dôvodu nechráni.

Bezpečný je jeden regulárny výraz pre všetky blokované priečinky, ktorý stojí pred blokom PHP. Pokrýva aj zriedka používané prípony:

```nginx
server {
    # ... základná konfigurácia ...

    # 1. Blokovanie zapisovateľných priečinkov, MUSÍ stáť pred blokom PHP
    location ~* ^/(uploads|media|cache|tmp|export)/.*\.(php\d?|phtml|phar|pht|phps)$ {
        deny all;
    }

    # 2. Všeobecný blok PHP: odovzdávať len existujúce súbory
    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;
    }
}
```

Názvy priečinkov prispôsobte svojej inventúre. Pri aplikáciách s jediným vstupným bodom je cesta cez zoznam povolených ešte silnejšia; vzor ukazuje [Bezpečná konfigurácia Nginx pre PHP](https://phpsos.de/sk/blog/nginx-fuer-php-absichern/).

## Apache a PHP-FPM: blokovanie na správnom mieste

V Apache patrí blokovanie do konfigurácie servera alebo do VirtualHost. Súbor `.htaccess` v priečinku s uploadmi je nevhodný, pretože ho môže zmeniť každý, kto tam smie zapisovať. Pre celý webový koreň preto platí `AllowOverride None`. Podľa dokumentácie Apache je `AllowOverride` povolené len v blokoch `<Directory>` bez regulárnych výrazov, nastavte ho teda na webovom koreni a blokovanie cez `<DirectoryMatch>` pod ním:

```apache
<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>
```

Ak ešte beží mod_php, doplňte v tom istom bloku `php_admin_flag engine off`. Pri PHP-FPM pôsobí druhá zábrana v poole: `security.limit_extensions` určuje, ktoré prípony FPM vôbec vykoná. Podľa príručky PHP je štandard `.php .phar`; odporúča sa obmedzenie na `.php`.

```ini
; v poole, napr. /etc/php/8.3/fpm/pool.d/seite1.conf
security.limit_extensions = .php
```

## Test neškodným súborom

Či blokovanie zaberá, ukáže len test. Do každého blokovaného priečinka nakrátko uložte súbor, ktorý iba vypíše text, otvorte ho cez doménu a potom ho zmažte.

1. Skontrolovať konfiguráciu: `nginx -t` resp. `apachectl configtest`, potom znova načítať.
2. Vytvoriť testovací súbor, napríklad `uploads/sperrtest.php` s obsahom `<?php echo 'ausgefuehrt';`.
3. Otvoriť pomocou `curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/uploads/sperrtest.php`. Očakáva sa `403`.
4. Ak sa namiesto toho objaví `200` a text „ausgefuehrt“, blokovanie nezaberá. Skontrolovať konfiguráciu a poradie.
5. Testovací súbor zmazať a test zopakovať pre každý priečinok a každý web.

> **Dôležité:**
> Ak pri inventúre nájdete v zapisovateľných priečinkoch už neznáme súbory PHP, nemažte nič unáhlene. Najprv zabezpečte stav a protokoly, pretože tieto súbory sú dôkazmi. Ako potom postupovať, opisuje [Rozpoznanie a odstránenie webshellov](https://phpsos.de/sk/ratgeber/webshell-erkennen/).

Ako sa funkcie uploadu v kóde stavajú bezpečne, s kontrolou typu a uložením mimo webového koreňa, uvádza sprievodca [Bezpečná implementácia nahrávania súborov v PHP](https://phpsos.de/sk/ratgeber/datei-upload-sicher/).

## Záver: zapisovať áno, vykonávať nie

Blokovanie vykonávania v zapisovateľných priečinkoch je jedno z najúčinnejších jednotlivých opatrení proti trvalým zadným vrátkam. Stojí niekoľko riadkov konfigurácie a pri čisto postavených aplikáciách nič nepokazí. Rozhodujúce sú tri veci: úplná inventúra namiesto len zjavného priečinka s uploadmi, správne poradie v Nginx resp. správna úroveň v Apache a skutočný test neškodným súborom.

Doplnené o oddelených vlastníkov pre programový kód, `security.limit_extensions` v poole a pravidelné hľadanie nových súborov PHP vznikne stav, v ktorom je uložený súbor síce nepríjemný, ale takmer nepoužiteľný. To nenahrádza ani aktualizáciu, ani hľadanie stôp, útočníkom však berie jeden z ich najdôležitejších nástrojov.

## Ako konkrétne pomáha PHP SOS?

- **Inventúra:** zistíme všetky zapisovateľné priečinky pre každý web a skontrolujeme ich na existujúce súbory PHP.
- **Nastaviť blokovanie:** zákazy vykonávania zapíšeme do Nginx, Apache a PHP-FPM, v správnom poradí a bez závislosti od `.htaccess`.
- **Testovať:** každé blokovanie preveríme neškodným súborom a výsledok zdokumentujeme.
- **Vyčistiť:** pri nálezoch preberáme zabezpečenie stôp a [odstránenie malvéru](https://phpsos.de/sk/leistungen/malware-entfernung/).


## Časté otázky

**Stačí na zákaz PHP súbor .htaccess v priečinku s uploadmi?**  
Nie spoľahlivo. Kto môže zapisovať do priečinka, môže zmeniť alebo nahradiť aj .htaccess. Blokovanie patrí do konfigurácie servera alebo do VirtualHost a pre webový koreň by mal platiť AllowOverride None.

**Ktoré priečinky musím zablokovať?**  
Všetky priečinky, do ktorých smie zapisovať používateľ PHP a ktoré sú dostupné cez webový server. Okrem priečinkov s uploadmi sú to často cache, temp, import, export a záložné adresáre. Zistíte ich hľadaním pod používateľom behu.

**Pokazí blokovanie môj web?**  
Spravidla nie, pretože v priečinkoch s uploadmi a cache u čisto postavených aplikácií neležia skripty, ktoré sa otvárajú priamo. Jednotlivé rozšírenia tam však predsa len ukladajú súbory PHP. Po prechode preto otestujte najdôležitejšie funkcie.

**Chráni blokovanie pred PHP2Shell?**  
Nie. PHP2Shell je zraniteľnosť v interpreteri PHP, ktorá sa uzavrie len aktualizáciou a reštartom všetkých workerov. Blokovanie však bráni tomu, aby sa uložený súbor neskôr otvoril cez prehliadač a využil ako trvalé zadné vrátko.

## Zdroje

- [Nginx: výber blokov location](https://nginx.org/en/docs/http/ngx_http_core_module.html)
- [Apache: základné funkcie (AllowOverride, FilesMatch)](https://httpd.apache.org/docs/2.4/mod/core.html)
- [Príručka PHP: konfigurácia FPM (security.limit_extensions)](https://www.php.net/manual/en/install.fpm.configuration.php)
- [OWASP Cheat Sheets (File Upload)](https://cheatsheetseries.owasp.org/)
