Kort sagt: Med PHP disable_functions spærrer I funktioner, hvormed PHP udfører systemkommandoer, f.eks. exec, shell_exec eller proc_open. Det gør angribernes næste skridt vanskeligere efter et indbrud. Indstillingen virker kun fra php.ini eller FPM-pool, skal passe til applikationen og erstatter ikke en opdatering.
Hvorfor disable_functions er fornuftigt netop nu
Ved PHP2Shell handler det om kørsel af skadelig kode på afstand uden login. De to sårbarheder CVE-2026-109618 og CVE-2026-109619 sidder i selve PHP-fortolkeren, rettet i PHP 8.5.12, 8.4.27, 8.3.36 og 8.2.35. Opdateringen er den eneste vej til at lukke dem.
Hærdning sætter ind et led senere. Den, der én gang kan køre kode på en server, vil som regel videre: starte systemkommandoer, hente værktøjer ned, indrette en varig bagdør. Mange af disse skridt går via få PHP-funktioner. Er de spærret, bliver vejen besværligere og mere påfaldende.
disable_functions er derfor ingen erstatning for patches, men en byggesten for det tilfælde, at noget trods al forsigtighed slipper igennem. Det gælder fremtidige sårbarheder lige så meget som PHP2Shell.
Hvad PHP disable_functions kan, og hvad det ikke kan
Indstillingen fjerner de nævnte funktioner fra kørselsmiljøet. Kalder et script en spærret funktion, afbryder PHP med en fejl. Spærringen gælder for enhver kode, der kører i denne PHP-proces, altså også for indsmuglet kode.
Grænserne bør I kende:
- Indstillingen er ikke et lukket beskyttelsesrum. PHP-udvidelser, fejl i fortolkeren eller programmer uden for PHP kan omgå den.
- Den forhindrer ikke, at en angriber læser eller skriver filer, som PHP-brugeren har adgang til. Dertil er filrettigheder og isolation ansvarlige.
- Den virker kun fra php.ini eller som
php_admin_value. Medini_set(),.user.inieller.htaccesskan den ikke sættes.
Mest får I ud af disable_functions sammen med en ren php.ini, egne brugere pr. website og restriktive filrettigheder. Grundlaget står i vejledningen Konfigurér php.ini sikkert.
Hvilke funktioner I bør spærre
For typiske websites uden behov for systemkommandoer har følgende liste vist sit værd. Den omfatter funktioner til at starte processer og til at styre kørende processer.
| Gruppe | Funktioner | Typisk legitim anvendelse |
|---|---|---|
| Udfør kommandoer | exec, shell_exec, system, passthru |
Billedbehandling, backups via script |
| Åbn processer | proc_open, popen |
Composer, PDF-værktøjer, mailafsendelse |
| Styr processer | proc_nice, proc_terminate, proc_get_status |
Køer, baggrundsjob |
| Procesadministration | pcntl_exec, pcntl_fork |
oftest kun på kommandolinjen |
| Signaler og rettigheder | posix_kill, posix_setuid |
sjældent i webdrift |
Som konfiguration ser det sådan ud:
; php.ini for web-driftsformen, f.eks. /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
Gælder listen ikke for alle websites på serveren, så sæt den pr. FPM-pool. Kontrollér efter genindlæsningen, hvilken liste der faktisk gælder i denne pool:
; /etc/php/8.3/fpm/pool.d/meine-seite.conf (uddrag)
php_admin_value[disable_functions] = exec,shell_exec,system,passthru,proc_open,popen
Kontrollér applikationen først: sådan undgår I driftsstop
Den, der sætter listen ukontrolleret, risikerer, at formindskelse af billeder, PDF-fakturaer eller mailafsendelse pludselig ikke længere virker. Søg derfor i koden efter de berørte funktioner først:
# Hvor og hvor ofte bruges funktionerne i koden?
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
Fund betyder ikke automatisk, at funktionen bruges i driften. Mange biblioteker kontrollerer først, om en funktion er tilgængelig, og viger ellers ud. Afgørende er en test i et staging-miljø med alle vigtige forløb: bestilling, faktura, formularafsendelse, billedupload, planlagte opgaver.
Kræver en applikation tvingende en af disse funktioner, så kontrollér producentens systemkrav på dennes officielle side. Ofte kan opgaven flyttes til en særskilt pool eller et kommandolinjescript, som ikke kan nås via nettet.
Aktivér indstillingen og kontrollér virkningen
Efter ændringen skal PHP læse konfigurationen ind igen. Kontrollér derefter værdien i jeres websites driftsform, ikke på kommandolinjen:
sudo systemctl reload php8.3-fpm
php-fpm8.3 -i | grep "^disable_functions"
# Kontrollér fejlloggen for kald af spærrede funktioner
sudo grep -i "has been disabled" /var/log/php/*.log | tail -20
Meddelelserne i fejlloggen er også senere værdifulde. Dukker der pludselig kald af spærrede funktioner op dér, selv om jeres applikation ikke bruger dem, kan det pege på indsmuglet kode. Hvordan I så går videre, beskriver vejledningen Opdag og fjern webshells.
Typiske fejl ved brug af disable_functions
I praksis strander hærdning sjældent på teknikken, men på småting. Disse fejl er særligt udbredte:
- Forkert fil ændret: Listen står kun i kommandolinjens php.ini, websitet kører via PHP-FPM og forbliver ubeskyttet.
- Ingen genstart: Filen er korrekt, men de kørende processer arbejder stadig med den gamle konfiguration.
- Spærret for bredt: Funktioner som
ini_setellermailbliver spærret med, og vigtige forløb afbrydes ubemærket. Fejl opdages så ofte først efter dage, f.eks. ved udeblevne ordrebekræftelser. - Sat én gang, aldrig kontrolleret: Efter en flytning, et skift af PHP-version eller en nyinstallation via hostingpanelet er listen forsvundet.
- Falsk tryghed: Spærringen opfattes som erstatning for opdateringer. Den lukker dog ingen sårbarhed i fortolkeren.
Tag kontrollen af den aktive værdi derfor med i jeres rutine efter hver PHP-opdatering. Et kort blik er nok, koster næsten ingen tid og forhindrer, at en hærdning stille går tabt.
Ved flere websites på en server: Opret for hvert website en egen pool med egen liste. Som supplement begrænser open_basedir de mapper, som PHP må tilgå.
Hvordan hjælper PHP SOS konkret?
- Vi gennemgår kode og forløb i jeres applikation for brugen af kritiske funktioner.
- Vi fastlægger en passende spærreliste pr. website og tester den før go-live.
- Vi kombinerer spærringen med pools, filrettigheder og logning til et sammenhængende hærdningskoncept.
- Vi dokumenterer indstillingerne og overvåger fejlloggen for påfaldende kald.
Hvordan det forløber som samlet pakke, beskriver ydelsen Serverhærdning til PHP-webservere.
Ofte stillede spørgsmål
Kan jeg sætte disable_functions via ini_set() eller .htaccess?
Nej. Indstillingen virker kun fra php.ini eller som php_admin_value i FPM-poolen henholdsvis i Apache-konfigurationen. Under kørslen kan den ikke sættes, og applikationen kan heller ikke frigive spærrede funktioner igen.
Beskytter disable_functions mod PHP2Shell?
Nej. PHP2Shell berører selve PHP-fortolkeren, sårbarheden lukkes kun af opdateringen. Spærrede funktioner kan dog begrænse en angribers råderum efter en vellykket udnyttelse.
Hvorfor viser php -i en anden liste end mit website?
Kommandolinjen læser ofte sin egen php.ini. For websitet tæller konfigurationen af PHP-FPM, mod_php eller LiteSpeed. Kontrollér derfor værdien i den driftsform, som jeres website kører via.
Hvilke applikationer har brug for proc_open eller exec?
Det afhænger af applikationen. Typisk er billedbehandling via eksterne programmer, PDF-generering, mailafsendelse via sendmail eller værktøjer som Composer. Kontrollér det i koden og i producentens systemkrav.