Īsi sakot: Lai augšupielādēs aizliegtu PHP izpildi, vispirms noskaidrojiet visas mapes, kurās PHP drīkst rakstīt, un tad katrā no tām nobloķējiet skriptu izpildi servera konfigurācijā, nevis ar .htaccess. Nginx bloķēšanai jāiedarbojas pirms vispārējā PHP bloka, Apache tā pieder VirtualHost ar AllowOverride None. security.limit_extensions = .php FPM pūlā un tests ar nekaitīgu failu darbu noslēdz.
Kāpēc tieši tagad svarīgas augšupielāžu mapes
Pēc kritiskas ievainojamības, piemēram, PHP2Shell, uzbrucēji reti grib izpildīt kodu tikai vienreiz. Viņi grib atgriezties, arī ja serveris vēlāk tiek ielāpots. Vienkāršākais ceļš tam ir webshell: neliels PHP fails, novietots rakstāmā mapē un vēlāk izsaukts caur pārlūku.
Ielāps šādu failu nenoņem. Kas kopš 2026. gada 20. oktobra bija tiešsaistē neielāpots, tam tāpēc jāatjaunina ne tikai sistēma, bet jāpārbauda arī, vai kaut kur nav jaunu PHP failu, un turpmāk jānovērš to izpilde. Kā atradumus interpretēt, apraksta PHP faili augšupielāžu mapē: atradumu pareiza interpretācija.
Izpildes bloķēšana ķeras pie otrā nosacījuma. Tā nenovērš, ka fails tiek novietots, bet novērš, ka serveris to uzskata par programmu.
Vispirms inventarizācija: kur PHP drīkst rakstīt?
Lielākā daļa pamācību min tikai augšupielāžu mapi. Praksē PHP lietojumprogramma raksta daudz vairāk vietās. Katrai no tām, kas ir sasniedzama caur tīmekļa serveri, vajadzīga bloķēšana.
| Mapes veids | Tipisks saturs | Kāpēc rakstāma |
|---|---|---|
| Augšupielādes, mediji | attēli, PDF, pielikumi | lietotāji un redakcija augšupielādē failus |
| Kešatmiņa | ģenerētas lapas, sīktēli | lietojumprogramma paātrina piegādi |
| Pagaidu, imports, eksports | CSV faili, starpstāvokļi | saskarnes un datu apmaiņa |
| Rezerves kopijas tīmekļa saknē | .zip, .sql |
paplašinājumi veido kopijas „uz vietas" |
| Žurnāli tīmekļa saknē | kļūdu un atkļūdošanas žurnāli | nepareizi konfigurētas lietojumprogrammas |
Kuras mapes tās ir jūsu serverī, parāda meklēšana ar izpildes lietotāja tiesībām. Tā neko nemaina:
# Visas mapes zem /var/www, kurās PHP lietotājs drīkst rakstīt
# (pielāgot lietotāju: www-data, nginx, apache vai savs pūla lietotājs)
sudo -u www-data find /var/www -type d -writable 2>/dev/null | sort
# Vai šajās mapēs jau ir PHP faili?
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
Ja pirmā meklēšana atgriež visu tīmekļa sakni, programmas kods pieder izpildes lietotājam. To vajadzētu mainīt iepriekš, kā apraksta ceļvedis Failu tiesības tīmekļa serverī. Citādi nav neviena mapes, kuru nevajadzētu bloķēt.
PHP izpildes aizliegšana augšupielādēs: Nginx
Nginx gadījumā izšķir secība. Saskaņā ar Nginx dokumentāciju regulārās izteiksmes tiek pārbaudītas konfigurācijas faila secībā, un uzvar pirmais trāpījums. Ja vispārējais bloks location ~ \.php$ atrodas pirms jūsu bloķēšanas, fails tiek izpildīts. Vienkāršs prefiksa location bez ^~ neaizsargā tā paša iemesla dēļ.
Droša ir regulāra izteiksme visām bloķētajām mapēm, kas atrodas pirms PHP bloka. Tā aptver arī reti izmantotus paplašinājumus:
server {
# ... pamata konfigurācija ...
# 1. Rakstāmo mapju bloķēšana, JĀATRODAS pirms PHP bloka
location ~* ^/(uploads|media|cache|tmp|export)/.*\.(php\d?|phtml|phar|pht|phps)$ {
deny all;
}
# 2. Vispārējs PHP bloks: nodot tikai esošus failus
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;
}
}
Mapju nosaukumus pielāgojiet savai inventarizācijai. Lietojumprogrammām ar vienu ieejas punktu ceļš caur atļauto sarakstu ir vēl stiprāks; paraugu rāda Nginx droša konfigurēšana PHP.
Apache un PHP-FPM: bloķēšana pareizajā vietā
Apache bloķēšana pieder servera konfigurācijā vai VirtualHost. .htaccess augšupielāžu mapē ir nepiemērots, jo to var mainīt ikviens, kam tur atļauts rakstīt. Visai tīmekļa saknei tāpēc spēkā ir AllowOverride None. Saskaņā ar Apache dokumentāciju AllowOverride ir atļauts tikai <Directory> blokos bez regulārajām izteiksmēm, tātad iestatiet to tīmekļa saknē, bet bloķēšanu ar <DirectoryMatch> zem tās:
<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>
Ja vēl darbojas mod_php, tajā pašā blokā papildiniet php_admin_flag engine off. PHP-FPM gadījumā otra barjera darbojas pūlā: security.limit_extensions nosaka, kurus paplašinājumus FPM vispār izpilda. Saskaņā ar PHP rokasgrāmatu noklusējums ir .php .phar; ieteicams ierobežojums uz .php.
; pūlā, piem., /etc/php/8.3/fpm/pool.d/seite1.conf
security.limit_extensions = .php
Testēšana ar nekaitīgu failu
Vai bloķēšana darbojas, parāda tikai tests. Katrā bloķētajā mapē uz īsu brīdi novietojiet failu, kas tikai izvada tekstu, izsauciet to caur domēnu un pēc tam izdzēsiet.
- Pārbaudīt konfigurāciju:
nginx -tresp.apachectl configtest, tad pārlādēt. - Izveidot testa failu, piemēram,
uploads/sperrtest.phpar saturu<?php echo 'ausgefuehrt';. - Izsaukt ar
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/uploads/sperrtest.php. Sagaidāms403. - Ja tā vietā parādās
200un teksts „ausgefuehrt", bloķēšana nedarbojas. Pārbaudīt konfigurāciju un secību. - Izdzēst testa failu un testu atkārtot katrai mapei un katrai vietnei.
Ja inventarizācijā rakstāmās mapēs atrodat jau nezināmus PHP failus, neizdzēsiet neko pārsteidzīgi. Vispirms nodrošiniet stāvokli un žurnālus, jo šie faili ir pierādījumi. Kā rīkoties tālāk, apraksta Webshell atpazīšana un noņemšana.
Kā augšupielādes funkcijas kodā droši veidot, ar tipa pārbaudi un glabāšanu ārpus tīmekļa saknes, rakstīts ceļvedī Failu augšupielāžu droša īstenošana PHP.
Secinājums: rakstīt jā, izpildīt nē
Izpildes bloķēšana rakstāmās mapēs ir viens no efektīvākajiem atsevišķajiem pasākumiem pret pastāvīgām slēptajām piekļuvēm. Tā maksā dažas konfigurācijas rindiņas un sakārtoti būvētām lietojumprogrammām neko nesabojā. Izšķirošas ir trīs lietas: pilna inventarizācija, nevis tikai acīmredzamā augšupielāžu mape, pareiza secība Nginx resp. pareizais līmenis Apache un īsts tests ar nekaitīgu failu.
Papildinot ar atsevišķiem īpašniekiem programmas kodam, security.limit_extensions pūlā un regulāru jaunu PHP failu meklēšanu, rodas stāvoklis, kurā novietots fails ir gan kaitinošs, bet tikko izmantojams. Tas neaizstāj ne atjauninājumu, ne pēdu meklēšanu, bet atņem uzbrucējiem vienu no viņu svarīgākajiem darbarīkiem.
Kā PHP SOS palīdz konkrēti?
- Inventarizācija: mēs noskaidrojam visas rakstāmās mapes katrai vietnei un pārbaudām, vai tajās nav PHP failu.
- Iestatīt bloķēšanu: mēs ierakstām izpildes bloķēšanas Nginx, Apache un PHP-FPM, pareizā secībā un bez
.htaccessatkarības. - Testēt: katru bloķēšanu mēs pārbaudām ar nekaitīgu failu un dokumentējam rezultātu.
- Attīrīt: atradumu gadījumā mēs uzņemamies pēdu nodrošināšanu un ļaunprogrammatūras noņemšanu.
Biežāk uzdotie jautājumi
Vai pietiek ar .htaccess augšupielāžu mapē, lai aizliegtu PHP?
Ne droši. Kas var rakstīt mapē, tas var mainīt vai aizstāt arī .htaccess. Bloķēšanai jāatrodas servera konfigurācijā vai VirtualHost, un tīmekļa saknei jādarbojas AllowOverride None.
Kuras mapes man jābloķē?
Visas mapes, kurās PHP lietotājam atļauts rakstīt un kuras ir sasniedzamas caur tīmekļa serveri. Līdzās augšupielāžu mapēm tās bieži ir kešatmiņas, pagaidu, importa, eksporta un rezerves kopiju direktorijas. Noskaidrojiet tās ar meklēšanu kā izpildes lietotājs.
Vai bloķēšana sabojās manu vietni?
Parasti nē, jo augšupielāžu un kešatmiņas mapēs sakārtotās lietojumprogrammās nav skriptu, kas tiek izsaukti tieši. Taču atsevišķi paplašinājumi tur tomēr novieto PHP failus. Tāpēc pēc pārejas pārbaudiet svarīgākās funkcijas.
Vai bloķēšana aizsargā pret PHP2Shell?
Nē. PHP2Shell ir ievainojamība PHP interpretatorā, ko aizver tikai atjauninājums un visu worker procesu pārstartēšana. Bloķēšana tomēr novērš, ka novietots fails vēlāk tiek izsaukts caur pārlūku un izmantots kā pastāvīga slēpta piekļuve.