Kort sagt: Med PHP disable_functions spärrar ni funktioner som PHP kör systemkommandon med, till exempel exec, shell_exec eller proc_open. Det försvårar nästa steg för angripare efter ett intrång. Inställningen fungerar bara från php.ini eller FPM-pool, måste passa applikationen och ersätter inte en uppdatering.
Varför disable_functions är meningsfullt just nu
PHP2Shell handlar om att köra skadlig kod på distans utan inloggning. De två sårbarheterna CVE-2026-109618 och CVE-2026-109619 finns i själva PHP-tolken och är åtgärdade i PHP 8.5.12, 8.4.27, 8.3.36 och 8.2.35. Uppdateringen är det enda sättet att stänga dem.
Härdning sätter in ett lager senare. Den som en gång kan köra kod på en server vill oftast gå vidare: starta systemkommandon, ladda ned verktyg, upprätta en bestående bakdörr. Många av de stegen går via ett fåtal PHP-funktioner. Är de spärrade blir vägen besvärligare och mer iögonfallande.
disable_functions är därför ingen ersättning för patchar utan en byggsten för det fall att något trots all försiktighet tar sig igenom. Det gäller framtida sårbarheter lika mycket som PHP2Shell.
Vad PHP disable_functions åstadkommer och vad det inte gör
Inställningen tar bort de angivna funktionerna ur körmiljön. Anropar ett skript en spärrad funktion avbryter PHP med ett fel. Spärren gäller all kod som körs i den PHP-processen, alltså även insmugglad kod.
Gränserna bör ni känna till:
- Inställningen är inget slutet skyddsrum. PHP-tillägg, fel i tolken eller program utanför PHP kan kringgå den.
- Den hindrar inte en angripare från att läsa eller skriva filer som PHP-användaren har åtkomst till. För det ansvarar filrättigheter och isolering.
- Den fungerar bara från php.ini eller som
php_admin_value. Medini_set(),.user.inieller.htaccessgår den inte att sätta.
Mest ger disable_functions tillsammans med en ren php.ini, egna användare per webbplats och restriktiva filrättigheter. Grunderna finns i guiden Konfigurera php.ini säkert.
Vilka funktioner ni bör spärra
För typiska webbplatser utan behov av systemkommandon har följande lista visat sig fungera. Den omfattar funktioner för att starta processer och styra pågående processer.
| Grupp | Funktioner | Typisk legitim användning |
|---|---|---|
| Köra kommandon | exec, shell_exec, system, passthru |
Bildbehandling, säkerhetskopior via skript |
| Öppna processer | proc_open, popen |
Composer, PDF-verktyg, e-postutskick |
| Styra processer | proc_nice, proc_terminate, proc_get_status |
Köer, bakgrundsjobb |
| Processhantering | pcntl_exec, pcntl_fork |
oftast bara på kommandoraden |
| Signaler och rättigheter | posix_kill, posix_setuid |
sällan i webbdrift |
Som konfiguration ser det ut så här:
; php.ini för webbdriftläget, t.ex. /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äller listan inte alla webbplatser på servern, sätt den per FPM-pool. Kontrollera efter omladdningen vilken lista som faktiskt gäller i den poolen:
; /etc/php/8.3/fpm/pool.d/meine-seite.conf (utdrag)
php_admin_value[disable_functions] = exec,shell_exec,system,passthru,proc_open,popen
Kontrollera applikationen i förväg: så undviker ni driftstopp
Den som sätter listan ogranskad riskerar att bildförminskning, PDF-fakturor eller e-postutskick plötsligt slutar fungera. Sök därför i förväg i koden efter de berörda funktionerna:
# Var och hur ofta används funktionerna 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
Träffar betyder inte automatiskt att funktionen behövs i drift. Många bibliotek kontrollerar först om en funktion är tillgänglig och väljer annars en annan väg. Avgörande är ett test i en stagingmiljö med alla viktiga flöden: beställning, faktura, formulärutskick, bilduppladdning, schemalagda uppgifter.
Kräver en applikation tvingande en av dessa funktioner, kontrollera tillverkarens systemkrav på tillverkarens officiella sida. Ofta går uppgiften att flytta till en separat pool eller ett kommandoradsskript som inte nås via webben.
Aktivera inställningen och kontrollera effekten
Efter ändringen måste PHP läsa in konfigurationen på nytt. Kontrollera därefter värdet i er webbplats driftläge, inte på kommandoraden:
sudo systemctl reload php8.3-fpm
php-fpm8.3 -i | grep "^disable_functions"
# Kontrollera felloggen efter anrop av spärrade funktioner
sudo grep -i "has been disabled" /var/log/php/*.log | tail -20
Meddelandena i felloggen är värdefulla även senare. Dyker det plötsligt upp anrop av spärrade funktioner fast er applikation inte använder dem kan det tyda på insmugglad kod. Hur ni då går vidare beskriver guiden Upptäcka och ta bort webshell.
Typiska fel vid användning av disable_functions
I praktiken faller härdningen sällan på tekniken utan på småsaker. De här felen är särskilt vanliga:
- Fel fil ändrad: Listan står bara i php.ini för kommandoraden, webbplatsen körs via PHP-FPM och förblir oskyddad.
- Ingen omstart: Filen är rätt, men de körande processerna arbetar fortfarande med den gamla konfigurationen.
- För brett spärrat: Funktioner som
ini_setellermailspärras också, och viktiga flöden avbryts obemärkt. Felen märks då ofta först efter flera dagar, till exempel genom uteblivna orderbekräftelser. - Satt en gång, aldrig kontrollerad: Efter en flytt, ett byte av PHP-version eller en nyinstallation via hostingpanelen har listan försvunnit.
- Falsk trygghet: Spärren uppfattas som en ersättning för uppdateringar. Den stänger dock ingen sårbarhet i tolken.
Ta därför med kontrollen av det aktiva värdet i er rutin efter varje PHP-uppdatering. En kort blick räcker, kostar knappt någon tid och hindrar att en härdning tyst går förlorad.
Vid flera webbplatser på en server: Skapa en egen pool med egen lista för varje webbplats. Som komplement begränsar open_basedir vilka kataloger PHP får komma åt.
Hur hjälper PHP SOS konkret?
- Vi granskar kod och flöden i er applikation efter användningen av kritiska funktioner.
- Vi fastställer en lämplig spärrlista per webbplats och testar den före driftsättning.
- Vi kombinerar spärren med pooler, filrättigheter och loggning till ett sammanhängande härdningskoncept.
- Vi dokumenterar inställningarna och övervakar felloggen efter avvikande anrop.
Hur det går till som helhetspaket beskriver tjänsten Serverhärdning för PHP-webbservrar.
Vanliga frågor
Kan jag sätta disable_functions med ini_set() eller .htaccess?
Nej. Inställningen fungerar bara från php.ini eller som php_admin_value i FPM-poolen respektive Apache-konfigurationen. Under körning går den inte att sätta, och applikationen kan inte heller häva spärrade funktioner.
Skyddar disable_functions mot PHP2Shell?
Nej. PHP2Shell berör själva PHP-tolken och sårbarheten stängs bara genom uppdateringen. Spärrade funktioner kan dock begränsa en angripares handlingsutrymme efter ett lyckat utnyttjande.
Varför visar php -i en annan lista än min webbplats?
Kommandoraden läser ofta en egen php.ini. För webbplatsen gäller konfigurationen för PHP-FPM, mod_php eller LiteSpeed. Kontrollera därför värdet i det driftläge som er webbplats körs i.
Vilka applikationer behöver proc_open eller exec?
Det beror på applikationen. Typiskt är bildbehandling via externa program, PDF-generering, e-postutskick via sendmail eller verktyg som Composer. Kontrollera det i koden och i tillverkarens systemkrav.