Aktuel situation: PHP2Shell. To kritiske PHP-sårbarheder (CVSS 9,2) tillader skadelig kode uden login. Rettelser siden 21.10.2026.Hvad der skal gøres nu →

Brug PHP disable_functions rigtigt

Med disable_functions spærrer I risikable PHP-funktioner. Sådan fastlægger I listen, så den passer til jeres applikation, uden at lamme websitet.

Status 5 min. læsetidVejledninger

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. Med ini_set(), .user.ini eller .htaccess kan 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_set eller mail bliver 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.

Tip

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.

Kilder

Akut kontakt

Hver time tæller. Skriv til os nu.

Beskriv kort system, PHP-version og observation. Vi vender tilbage, afklarer situationen og arbejder på afstand, indtil hændelsen er afsluttet og dokumenteret.

Akut hjælp