Trumpai: Su PHP disable_functions užblokuojate funkcijas, per kurias PHP vykdo sistemos komandas, pavyzdžiui, exec, shell_exec ar proc_open. Tai užpuolikui po įsilaužimo apsunkina kitą žingsnį. Nustatymas veikia tik iš php.ini ar FPM baseino, turi derėti su programa ir neatstoja atnaujinimo.
Kodėl disable_functions dabar ypač prasminga
PHP2Shell atveju kalbama apie nuotolinį kenkėjiško kodo vykdymą be prisijungimo. Abu pažeidžiamumai, CVE-2026-109618 ir CVE-2026-109619, glūdi pačiame PHP interpretatoriuje, ištaisyti PHP 8.5.12, 8.4.27, 8.3.36 ir 8.2.35 versijose. Atnaujinimas yra vienintelis būdas jas uždaryti.
Sutvirtinimas veikia vienu lygiu vėliau. Kas kartą gali vykdyti kodą serveryje, paprastai nori eiti toliau: paleisti sistemos komandas, parsisiųsti įrankius, įrengti nuolatines užpakalines duris. Daugelis šių žingsnių vyksta per kelias PHP funkcijas. Kai jos užblokuotos, kelias tampa sunkesnis ir labiau krenta į akis.
Todėl disable_functions nėra pataisų pakaitalas, o dalis apsaugos tam atvejui, jei nepaisant visos atsargos kas nors prasiskverbtų. Tai galioja ir būsimiems pažeidžiamumams, ir PHP2Shell.
Ką PHP disable_functions duoda ir ko neduoda
Nustatymas pašalina nurodytas funkcijas iš vykdymo aplinkos. Jei skriptas iškviečia užblokuotą funkciją, PHP nutraukia darbą su klaida. Blokavimas galioja kiekvienam kodui, kuris vykdomas tame PHP procese, taigi ir įterptam kodui.
Ribas verta žinoti:
- Nustatymas nėra uždara apsauginė erdvė. PHP plėtiniai, interpretatoriaus klaidos ar programos už PHP ribų gali jį apeiti.
- Jis nesutrukdo užpuolikui skaityti ar rašyti failų, prie kurių PHP naudotojas turi prieigą. Už tai atsako failų teisės ir izoliacija.
- Jis veikia tik iš php.ini arba kaip
php_admin_value. Suini_set(),.user.iniar.htaccessjo nustatyti negalima.
Daugiausia disable_functions duoda kartu su tvarkingu php.ini, atskirais naudotojais kiekvienai svetainei ir ribojančiomis failų teisėmis. Pagrindus rasite vadove Kaip saugiai sukonfigūruoti php.ini.
Kurias funkcijas reikėtų užblokuoti
Tipinėms svetainėms, kurioms sistemos komandų nereikia, pasiteisino toks sąrašas. Jame yra procesų paleidimo ir veikiančių procesų valdymo funkcijos.
| Grupė | Funkcijos | Tipinis teisėtas naudojimas |
|---|---|---|
| Komandų vykdymas | exec, shell_exec, system, passthru |
Paveikslėlių apdorojimas, atsarginės kopijos per skriptą |
| Procesų atidarymas | proc_open, popen |
Composer, PDF įrankiai, laiškų siuntimas |
| Procesų valdymas | proc_nice, proc_terminate, proc_get_status |
Eilės, foninės užduotys |
| Procesų administravimas | pcntl_exec, pcntl_fork |
dažniausiai tik komandinėje eilutėje |
| Signalai ir teisės | posix_kill, posix_setuid |
retai žiniatinklio veikloje |
Kaip konfigūracija tai atrodo taip:
; žiniatinklio veikimo režimo php.ini, pvz., /etc/php/8.3/fpm/php.ini
disable_functions = exec,shell_exec,system,passthru,proc_open,popen,proc_nice,proc_terminate,proc_get_status,pcntl_exec,pcntl_fork,posix_kill,posix_setuid
Jei sąrašas negalioja visoms serverio svetainėms, nustatykite jį kiekvienam FPM baseinui. Po perkrovimo patikrinkite, koks sąrašas tame baseine iš tikrųjų galioja:
; /etc/php/8.3/fpm/pool.d/meine-seite.conf (ištrauka)
php_admin_value[disable_functions] = exec,shell_exec,system,passthru,proc_open,popen
Programos patikra iš anksto: kaip išvengti sutrikimų
Kas sąrašą nustato nepatikrinęs, rizikuoja, kad paveikslėlių mažinimas, PDF sąskaitos ar laiškų siuntimas staiga nustos veikti. Todėl iš anksto kode ieškokite paveiktų funkcijų:
# Kur ir kaip dažnai funkcijos naudojamos kode?
grep -rnoE "\b(exec|shell_exec|system|passthru|proc_open|popen|pcntl_exec)\s*\(" /var/www/meine-seite --include="*.php" \
| cut -d: -f1 | sort | uniq -c | sort -rn | head -30
Radiniai automatiškai nereiškia, kad funkcijos veikloje reikia. Daugelis bibliotekų pirmiausia patikrina, ar funkcija prieinama, ir kitu atveju pasirenka kitą kelią. Lemia testas staging aplinkoje su visais svarbiais procesais: užsakymu, sąskaita, formos siuntimu, paveikslėlio įkėlimu, suplanuotomis užduotimis.
Jei programa privalomai reikalauja vienos iš šių funkcijų, patikrinkite gamintojo sistemos reikalavimus jo oficialioje svetainėje. Dažnai užduotį galima perkelti į atskirą baseiną arba komandinės eilutės skriptą, kuris nepasiekiamas per žiniatinklį.
Nustatymo aktyvavimas ir poveikio patikra
Po pakeitimo PHP turi iš naujo perskaityti konfigūraciją. Po to patikrinkite reikšmę savo svetainės veikimo režime, o ne komandinėje eilutėje:
sudo systemctl reload php8.3-fpm
php-fpm8.3 -i | grep "^disable_functions"
# Klaidų žurnale patikrinti užblokuotų funkcijų iškvietimus
sudo grep -i "has been disabled" /var/log/php/*.log | tail -20
Klaidų žurnalo pranešimai vertingi ir vėliau. Jei ten staiga atsiranda užblokuotų funkcijų iškvietimų, nors jūsų programa jų nenaudoja, tai gali rodyti įterptą kodą. Kaip elgtis toliau, aprašo vadovas Webshell aptikimas ir šalinimas.
Tipinės disable_functions naudojimo klaidos
Praktikoje sutvirtinimas retai strigsta dėl technikos, dažniau dėl smulkmenų. Šios klaidos ypač paplitusios:
- Pakeistas ne tas failas: sąrašas yra tik komandinės eilutės php.ini, o svetainė veikia per PHP-FPM ir lieka neapsaugota.
- Nepaleista iš naujo: failas teisingas, bet veikiantys procesai dar dirba su sena konfigūracija.
- Užblokuota per plačiai: kartu užblokuojamos funkcijos, tokios kaip
ini_setarmail, ir svarbūs procesai nepastebimai nutrūksta. Klaidos tuomet dažnai pastebimos tik po kelių dienų, pavyzdžiui, kai neateina užsakymų patvirtinimai. - Nustatyta vieną kartą ir niekada nepatikrinta: po perkėlimo, PHP versijos keitimo ar naujo įdiegimo per hostingo skydelį sąrašas dingo.
- Klaidingas saugumo jausmas: blokavimas suprantamas kaip atnaujinimų pakaitalas. Tačiau jis neuždaro pažeidžiamumo interpretatoriuje.
Todėl aktyvios reikšmės patikrą įtraukite į savo rutiną po kiekvieno PHP atnaujinimo. Užtenka trumpos peržiūros, ji beveik nieko nekainuoja ir apsaugo, kad sutvirtinimas nepasimestų tyliai.
Kai viename serveryje yra kelios svetainės: kiekvienai svetainei sukurkite atskirą baseiną su savo sąrašu. Papildomai open_basedir apriboja katalogus, prie kurių PHP gali kreiptis.
Kaip PHP SOS padeda konkrečiai?
- Tikriname jūsų programos kodą ir procesus dėl kritinių funkcijų naudojimo.
- Kiekvienai svetainei nustatome tinkamą blokavimo sąrašą ir išbandome jį prieš paleidžiant gyvai.
- Blokavimą derename su baseinais, failų teisėmis ir registravimu į darnią sutvirtinimo koncepciją.
- Nustatymus dokumentuojame ir stebime klaidų žurnalą dėl įtartinų iškvietimų.
Kaip tai vyksta kaip visas paketas, aprašo paslauga PHP žiniatinklio serverių sutvirtinimas.
Dažni klausimai
Ar disable_functions galiu nustatyti per ini_set() arba .htaccess?
Ne. Nustatymas veikia tik iš php.ini arba kaip php_admin_value FPM baseine ar Apache konfigūracijoje. Vykdymo metu jo nustatyti negalima, o programa užblokuotų funkcijų taip pat negali vėl atblokuoti.
Ar disable_functions apsaugo nuo PHP2Shell?
Ne. PHP2Shell paveikia patį PHP interpretatorių, o pažeidžiamumą uždaro tik atnaujinimas. Tačiau užblokuotos funkcijos gali apriboti užpuoliko veikimo laisvę po sėkmingo išnaudojimo.
Kodėl php -i rodo kitokį sąrašą nei mano svetainė?
Komandinė eilutė dažnai skaito savo php.ini. Svetainei svarbi PHP-FPM, mod_php ar LiteSpeed konfigūracija. Todėl reikšmę tikrinkite tame veikimo režime, per kurį veikia jūsų svetainė.
Kurioms programoms reikia proc_open ar exec?
Tai priklauso nuo programos. Tipiški pavyzdžiai: paveikslėlių apdorojimas išorinėmis programomis, PDF kūrimas, laiškų siuntimas per sendmail ar įrankiai, tokie kaip Composer. Patikrinkite tai kode ir gamintojo sistemos reikalavimuose.