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 →

php_admin_value: Lås indstillinger mod overskrivning

En sikkerhedsindstilling nytter lidt, hvis applikationen ændrer den igen med en enkelt kodelinje. Med php_admin_value og php_admin_flag fastlægger I værdier bindende for PHP-FPM og Apache.

Status 5 min. læsetidHærdning og konfiguration

Kort sagt: php_admin_value og php_admin_flag sætter PHP-indstillinger i PHP-FPM-poolen eller i Apache-konfigurationen, så applikationer hverken kan ændre dem med ini_set() eller med .htaccess. php.net kræver netop det til PHP2Shell-overgangsforanstaltningerne, f.eks. for memory_limit=-1. Efter indstillingen skal tjenesten genstartes, og værdien bør kontrolleres i webkonteksten.

Hvorfor "sat" ikke betyder "låst"

I dagene efter den 21. oktober 2026 har mange administratorer skrevet php.nets overgangsforanstaltninger ind i deres php.ini. En detalje i anbefalingen gik ofte tabt: memory_limit=-1 skal være sat, så applikationer ikke kan overskrive den. php.net nævner udtrykkeligt php_admin_value i FPM-poolen eller i Apache-konfigurationen hertil.

Årsagen er enkel. Mange CMS, shops og frameworks sætter deres egne værdier, f.eks. en højere hukommelsesgrænse til importer. Står værdien kun i php.ini, overskriver applikationen den ved næste kald. Beskyttelsesforanstaltningen findes så på papiret, men ikke i den kørende proces.

Det berører ikke kun PHP2Shell. Hver hærdning, fra slukkede fejludskrifter til upload-grænser, er kun så stærk som sit svageste niveau.

Hvem der overhovedet må ændre PHP-indstillinger

PHP kender fire ændringstilstande. Hver indstilling har én af dem, og den bestemmer, på hvilke steder den kan sættes. Betydningerne stammer fra PHP-manualen.

Tilstand Hvor værdien kan sættes Eksempler
INI_USER i scriptet med ini_set() og i .user.ini få køretidsværdier
INI_PERDIR php.ini, .htaccess, httpd.conf, .user.ini post_max_size, session.upload_progress.enabled
INI_SYSTEM kun php.ini eller httpd.conf file_uploads, disable_functions
INI_ALL overalt, også med ini_set() memory_limit, display_errors, open_basedir

Farlige er først og fremmest INI_ALL-værdier: De kan ændres fra ethvert script. INI_PERDIR-værdier kan ganske vist ikke ændres med ini_set(), men nok via en .htaccess ved mod_php eller en .user.ini ved PHP-FPM. Den, der har skriverettigheder i webroden, altså også indsmuglet kode, kan oprette sådanne filer.

php_admin_value i FPM-poolen og i Apache

Ved PHP-FPM står værdierne i pool-filen. PHP-manualen fastslår: Værdier sat med php_admin_value og php_admin_flag kan ikke overskrives med ini_set(). Til til/fra-værdier bruger I php_admin_flag, til alle andre php_admin_value.

; /etc/php/8.3/fpm/pool.d/seite1.conf (uddrag)
[seite1]
user = seite1
group = seite1
listen = /run/php/seite1.sock

php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/seite1-fehler.log
php_admin_value[open_basedir] = /var/www/seite1/:/tmp/seite1/

memory_limit=-1 hører ifølge php.net kun sammen med en hukommelsesgrænse via container eller cgroup hjemme i konfigurationen. Hvordan det lykkes med systemd, står i indlægget Sæt hukommelsesgrænser med systemd og cgroups.

Ved Apache med mod_php hører direktiverne hjemme i serverkonfigurationen eller VirtualHost. Ifølge PHP-manualen er de ikke tilladt i .htaccess, og når de først er sat, kan hverken .htaccess eller ini_set() ændre dem.

<VirtualHost *:443>
    ServerName www.example.de
    DocumentRoot /var/www/seite1/public
    <IfModule php_module>
        php_admin_value memory_limit -1
        php_admin_value post_max_size 32M
        php_admin_value upload_max_filesize 24M
        php_admin_flag session.upload_progress.enabled off
        php_admin_flag display_errors off
    </IfModule>
</VirtualHost>

To finesser fra manualen: For at slette en tidligere sat værdi bruger I none som værdi. Og PHP-konstanter som E_ALL har ingen betydning i Apache-konfigurationen; for error_reporting skal I dér angive talværdien.

Hvilke værdier I bør låse

Ikke hver indstilling behøver at være låst. Fornuftigt er det for alt, hvad der angår sikkerhed eller tjener som overgangsforanstaltning:

  1. php.nets PHP2Shell-overgangsværdier: memory_limit, post_max_size, upload_max_filesize, session.upload_progress.enabled og på PHP 8.5 fatal_error_backtraces.
  2. Fejlvisning og protokollering: display_errors, display_startup_errors, log_errors, error_log.
  3. Filadgang og isolation: open_basedir, upload_tmp_dir, session.save_path.
  4. Netværksadgange fra PHP: allow_url_include og, hvis applikationen ikke har brug for det, allow_url_fopen.
  5. Spærrede funktioner via disable_functions, som i poolen ifølge manualen supplerer php.ini-listen og ikke erstatter den. Detaljer i vejledningen Brug disable_functions rigtigt.

Ved session.upload_progress.enabled er låsningen særligt vigtig, fordi værdien ellers kunne slås til igen via en .user.ini. Mere herom under Slå session.upload_progress fra: rigtigt og varigt.

Kontrollér, at låsen virker

Efter hver ændring genstarter I tjenesten og kontrollerer værdien i webkonteksten. En kort, straks slettet kontrolfil viser, om poolen holder værdien, også når applikationen vil ændre den:

<?php
// Kontrolfil: læg den kortvarigt ud, kald den én gang via domænet, slet den straks
header('Content-Type: text/plain');
$vorher = ini_get('memory_limit');
$versuch = @ini_set('memory_limit', '256M');
echo "memory_limit: $vorher\n";
echo 'Änderung per ini_set() ', ($versuch === false ? 'blockiert' : 'MÖGLICH'), "\n";

Forventet er -1 og "blockiert". Lyder outputtet "MÖGLICH", er værdien ikke sat via php_admin_value, eller tjenesten er endnu ikke genstartet. Gentag kontrollen for hver pool og hver PHP-version.

Tip

Hold de låste værdier samlet et centralt sted, f.eks. i en pool-skabelon eller i jeres konfigurationsstyring. Hostingpaneler overskriver til dels håndændrede pool-filer ved næste lagring; dér hører værdierne hjemme i de felter, som panelet har afsat til formålet.

Hvordan PHP samlet ordner sine konfigurationsniveauer, forklarer php.ini forklaret: Opbygning, niveauer og forrang. De fuldstændige overgangsforanstaltninger står under Akutforanstaltninger, hvis I endnu ikke kan patche.

Konklusion: Først låst er virkelig sat

php.nets overgangsforanstaltninger til PHP2Shell har bragt en skelnen ind i bevidstheden, som tidligere ofte blev overset: En værdi i php.ini er for mange indstillinger kun et forslag, en værdi i php_admin_value en forskrift. For komfortværdier som tidszonen er forskellen uvæsentlig. For sikkerhedsindstillinger og overgangsforanstaltninger afgør den, om foranstaltningen overhovedet virker i den løbende drift.

Indsatsen er overskuelig: en håndfuld linjer pr. pool eller VirtualHost, en genstart, en kort kontrol. Hold listen over låste værdier lille og begrundet, så udviklere kan forstå, hvorfor deres applikation ikke må ændre en værdi. Og vedligehold listen i jeres skabeloner, så nye websites arver den automatisk.

Hvordan hjælper PHP SOS konkret?

  • Udlæs niveauerne: Vi finder for hvert website ud af, hvilke værdier fra php.ini, pool, Apache, .htaccess eller .user.ini der faktisk gælder.
  • Sæt låse: Sikkerhedsrelevante værdier og PHP2Shell-overgangsforanstaltningerne indfører vi som php_admin_value henholdsvis php_admin_flag og genstarter tjenesterne.
  • Test applikationen: Vi kontrollerer, om applikationen kører fejlfrit med de låste værdier, og analyserer fejllogget.
  • Vedligehold skabeloner: Inden for rammerne af serverhærdningen overfører vi værdierne til pool-skabeloner og dokumentation.

Ofte stillede spørgsmål

Hvad er forskellen på php_value og php_admin_value?

Begge sætter en PHP-indstilling. Værdier fra php_value kan applikationen senere ændre igen, f.eks. med ini_set() eller .htaccess. Værdier fra php_admin_value og php_admin_flag er ifølge PHP-manualen låst for ini_set(), ved Apache også for .htaccess.

Kan jeg skrive php_admin_value i en .htaccess-fil?

Nej. Ifølge PHP-manualen er php_admin_value ikke tilladt i .htaccess-filer. Den hører hjemme i Apache-serverkonfigurationen eller VirtualHost, ved PHP-FPM i pool-filen.

Hvad sker der, hvis en applikation vil ændre en låst værdi?

Kaldet til ini_set() mislykkes og returnerer false, den låste værdi består. Godt programmerede applikationer klarer det. Kontrollér alligevel fejllogget og de vigtigste funktioner efter omstillingen.

Skal jeg genstarte efter en ændring i poolen?

Ja. PHP-FPM læser pool-filerne ved start eller ved genindlæsning af tjenesten. Ved Apache med mod_php gælder det samme for serverkonfigurationen. Uden genstart kører den gamle værdi videre.

Kan disable_functions udvides i poolen?

Ja, med en særegenhed: Ifølge PHP-manualen overskriver disable_functions i FPM-poolen ikke værdierne fra php.ini, men supplerer dem. Poolen kan altså spærre yderligere funktioner, men ikke frigive nogen.

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