Kort sagt: PHP-udvidelser (extensions) er moduler i C, der supplerer PHP med funktioner, f.eks. databasedrivere (PDO), kryptering (Sodium, OpenSSL) eller bytekode-cachen OPcache. PHP-manualen skelner mellem core-, bundled-, external- og PECL-udvidelser. De indlæses via extension eller zend_extension i php.ini. Hver udvidelse kører i PHP-processen med dens rettigheder. Derfor gælder: indlæs kun, hvad der er brug for, og opdatér sammen med PHP.
Hvad er PHP-extensions?
PHP's kerne, Zend Engine, kan udføre kode, men meget af det, applikationer har brug for, sidder i udvidelser. De er skrevet i C og enten kompileret fast ind i PHP eller indlæst som delt bibliotek (.so under Linux, .dll under Windows) ved start.
Vigtigt for beslutningstagere: Udvidelser er ikke plugins til applikationen, men en del af PHP-runtime. De installeres af hostingudbyderen eller serveradministratoren, ikke af bureauet i CMS'et. Mangler en udvidelse, melder applikationen som regel en fejl ved installationen eller opdateringen.
Lige så vigtig er afgrænsningen til Composer-pakker. Composer installerer biblioteker, der er skrevet i PHP og ligger i projektmappen, f.eks. en mail- eller PDF-pakke. Udvidelser er derimod kompileret kode, som indlæses ved PHP's start og gælder for alle applikationer på serveren. Mange Composer-pakker forudsætter bestemte udvidelser og noterer det i deres composer.json med poster som ext-intl eller ext-sodium. Den, der vil kontrollere, om et projekt finder alle nødvendige udvidelser, kan i projektmappen udføre composer check-platform-reqs.
Hvilke arter af udvidelser findes der?
PHP-manualen inddeler udvidelser i fire grupper:
| Gruppe | Betydning ifølge manualen | Eksempler fra manualen |
|---|---|---|
| Core | del af PHP's kerne, kan ikke slås fra | Arrays, Date/Time, Hash, JSON, PCRE, SPL, Strings |
| Bundled | leveres med PHP | BC Math, Ctype, Fileinfo, Filter, GD, intl, mbstring, PDO, Sessions |
| External | leveres med PHP, kræver eksterne biblioteker | cURL, DOM, GMP, LDAP, OpenSSL, Sodium, Zip |
| PECL | kan fås via PECL, delvis med eksterne biblioteker | APCu, Memcached, MongoDB, Yaml |
Tilhørsforholdet kan ændre sig. Med PHP 8.4 blev udvidelserne IMAP, OCI8, PDO_OCI og pspell ifølge udgivelsessiden fjernet fra leverancen og flyttet til PECL. Den, der bruger dem, har efter opgraderingen brug for en separat installation, som ligeledes skal vedligeholdes.
Hvordan indlæses udvidelser?
Delte udvidelser indlæses ifølge manualen via direktivet extension i php.ini; Zend-udvidelser, der griber dybere ind i motoren, via zend_extension. Begge må kun stå i php.ini. Mappen fastlægger extension_dir, hvortil manualen anbefaler en absolut sti.
; normale udvidelser
extension=pdo_mysql
extension=sodium
extension=intl
; Zend-udvidelse: OPcache (indlæs før Xdebug, hvis begge er aktive)
zend_extension=opcache
Distributioner som Debian og Ubuntu lægger for hver udvidelse en egen lille .ini-fil i scan-mappen, f.eks. under /etc/php/8.3/mods-available/, og aktiverer dem pr. SAPI med phpenmod og phpdismod. Hvordan PHP indlæser disse filer, forklarer php.ini forklaret.
Udvidelser installeres som regel via pakkestyringen, f.eks. som pakken php8.3-intl. PECL-udvidelser kan bygges med pecl eller phpize. Ifølge manualen er PECL udfaset; anbefalet er PHP Installer for Extensions (PIE). Den, der bygger PHP helt selv, finder henvisninger under Kompilér PHP fra kildekode.
Kontrollere udvidelser: hvilke er virkelig indlæst?
De følgende kommandoer er rent læsende. Vær opmærksom på, at kommandolinjen kan indlæse andre udvidelser end websitet.
php -m # CLI's moduler
php-fpm8.3 -m # moduler i PHP-FPM 8.3 (navn afhænger af distributionen)
php --re sodium | head -n 5 # en udvidelses funktioner
php --ri opcache # en udvidelses konfiguration
php -r 'var_dump(extension_loaded("intl"));'
I koden kontrollerer applikationer med extension_loaded(), om en udvidelse findes, og med get_loaded_extensions(), hvilke der er indlæst:
<?php
$benoetigt = ['pdo_mysql', 'mbstring', 'intl', 'sodium'];
$fehlend = array_diff($benoetigt, array_map('strtolower', get_loaded_extensions()));
echo $fehlend ? 'Fehlt: ' . implode(', ', $fehlend) : 'Alle Erweiterungen vorhanden';
Udvidelser og sikkerhed: færre er bedre
Udvidelser kører i den samme proces som PHP og med de samme rettigheder. En fejl i en udvidelse kan derfor veje lige så tungt som en fejl i kernen. Heraf følger fire regler:
- Indlæs kun, hvad der er brug for. Hver ekstra udvidelse forøger angrebsfladen. Kontrollér jeres liste mod applikationens systemkrav.
- Opdatér sammen med PHP. Medfølgende udvidelser kommer med PHP-opdateringen. PECL- og tredjepartsudvidelser kræver egne opdateringer og skal passe til den nye PHP-version.
- Ingen udviklingsværktøjer i produktion. Debuggere og profilere som Xdebug hører kun hjemme i udviklingsmiljøer.
- Spær funktioner målrettet. Hvor udvidelser medbringer funktioner til systemkommandoer, hjælper Brug disable_functions rigtigt.
Ved PHP2Shell ligger sårbarhederne i PHP's kerne, ikke i en udvidelse. At slå moduler fra lukker dem ikke; nødvendig er opdateringen til 8.5.12, 8.4.27, 8.3.36 eller 8.2.35 med genstart af alle PHP-processer. Efter opdateringen bør I kontrollere, om alle udvidelser indlæses igen, for manglende moduler bliver ofte først opdaget ved bestemte funktioner. Hvordan I holder afhængigheder under kontrol på længere sigt, beskriver Hold afhængigheder aktuelle.
Hvordan hjælper PHP SOS konkret?
- Kortlægge beholdningen: Vi opregner pr. SAPI alle indlæste udvidelser med oprindelse og version.
- Rydde ud: Vi afstemmer listen med jeres applikations behov og deaktiverer overflødigt efter test.
- Opdatere: Som led i serverhærdningen bringer vi PHP og alle tredjepartsudvidelser op på en vedligeholdt status.
- Kontrollere efter opdateringer: Vi kontrollerer, at alle nødvendige moduler efter hver PHP-opdatering er indlæst igen.
Ofte stillede spørgsmål
Hvad er forskellen på extension og zend_extension?
Med extension indlæser PHP normale udvidelser som databasedrivere. Med zend_extension indlæses ifølge manualen Zend-udvidelser, der griber dybere ind i motoren, f.eks. OPcache eller Xdebug. Begge direktiver må kun stå i php.ini.
Hvordan ser jeg, hvilke udvidelser der er indlæst?
På kommandolinjen med php -m, for websitet via funktionen get_loaded_extensions() i en kortvarig kontrolfil eller via php-fpm -m for den pågældende version. Vær opmærksom på, at CLI og web-SAPI kan indlæse forskellige udvidelser.
Hvad er PECL, og hvad er PIE?
PECL er et register over PHP-udvidelser, som stilles til rådighed via PEAR-pakkesystemet. Ifølge PHP-manualen er PECL udfaset; anbefalet er i stedet PHP Installer for Extensions (PIE).
Lukker det PHP2Shell at slå en udvidelse fra?
Nej. PHP2Shell-sårbarhederne ligger i PHP's kerne, ikke i en udvidelse, der kan slås fra. Færre udvidelser mindsker angrebsfladen generelt, men erstatter ikke opdateringen til en rettet version.