# Local File Inclusion megelőzése PHP-ban: LFI és RFI

> Local File Inclusion megelőzése PHP-ban: engedélylisták a kérésből jövő útvonalak helyett, realpath-ellenőrzés, allow_url_include tiltása, open_basedir.

Forrás: https://phpsos.de/hu/ratgeber/lfi-rfi/  
Állapot: 2026. 10. 25.  
Szolgáltató: PHP SOS, PHP-vészhelyzeti segítség és szerverbiztonság. Azonnali segítség WhatsAppon: https://wa.me/491736494914?text=%C3%9Cdv%C3%B6zl%C3%B6m%2C%20PHP%20SOS%21%20Seg%C3%ADts%C3%A9gre%20van%20sz%C3%BCks%C3%A9g%C3%BCnk%20a%20PHP-szerver%C3%BCnkkel.%20C%C3%A9g%3A%20%E2%80%A6%20Weboldal%3A%20%E2%80%A6

**Röviden:** A Local File Inclusion PHP-ban akkor keletkezik, ha az `include`, a `require` vagy a fájlfüggvények olyan útvonalat használnak, amelyet a látogató befolyásolhat. A biztonságos megoldás egy rögzített engedélylista: a paraméter csak ismert értékek közül választ, maga az útvonal soha nem a kérésből származik. Szerveroldalon az `allow_url_include=Off`, az `open_basedir` és a szigorú fájljogosultságok egészítik ki a védelmet.

## Mi az a Local File Inclusion PHP-ban?

Sok régebbi PHP-alkalmazás egy egyszerű minta szerint tölt be oldalakat: a címben lévő paraméter határozza meg, melyik fájlt építik be. Ha ezt a paramétert ellenőrzés nélkül adják át az `include`-nak, a támadó más fájlokat kérhet a szerverről. Ártalmatlanabb esetben hozzáférési adatokat tartalmazó konfigurációs fájlokat olvas. Súlyosabb esetben rávesz a PHP-t arra, hogy olyan tartalmakat hajtson végre, amelyeket előtte máshol helyezett el, például egy feltöltésben vagy egy naplófájlban.

A vezetőség számára fontos: ez a rés ritkán a CMS magjában van, hanem többnyire saját fejlesztésekben, régi bővítményekben vagy gyorsan épített kiegészítő oldalakban. A mindennapokban nem tűnik fel, mert a weboldal normálisan működik.

A **Remote File Inclusion** esetén a PHP idegen címről tölt be kódot. Ennek feltétele, hogy az `allow_url_include` be legyen kapcsolva. Az aktuális PHP-verziókban ez a beállítás alapértelmezetten ki van kapcsolva, régi vagy hibásan beállított szervereken azonban még megtalálható.

### Tipikus sebezhető minták a kódban

Veszélyeztetettek azok a helyek, ahol a kérésből, a cookie-kból vagy az adatbázisból származó érték egy fájlútvonal részévé válik. Gyakori példák a nyelvváltók, amelyek egy paraméter szerint töltenek be nyelvi fájlt, a címben lévő paraméterrel történő oldalválasztás, a sablon- vagy témaválasztás és a dokumentumok letöltési szkriptjei. Az útvonal végére fűzött `.php` ezt nem védi megbízhatóan, mert a támadók kitérhetnek meglévő PHP-fájlokra.

Egy első áttekintést úgy kaphat, ha olyan beépítéseket keres, amelyek változókat tartalmaznak. Ez ártalmatlan találatokat is hoz, de megmutatja, hol kell alaposabban megnézni:

```bash
grep -rnE --include='*.php' '(include|require)(_once)?\s*\(?\s*\$' /var/www/projekt \
  | grep -v '/vendor/'
```

Minden találatot ellenőrizzen arra, honnan származik a változó, és befolyásolhatja-e egy látogató.

## A biztonságos minta: engedélylista a kérésből származó útvonal helyett

A legmegbízhatóbb védelem az, hogy a látogató csak egy kulcsot választ, és az alkalmazás maga dönti el, melyik fájl tartozik hozzá. Az útvonalat soha nem állítják össze bemenetekből.

```php
<?php
declare(strict_types=1);

$seiten = [
    'start'      => __DIR__ . '/../vorlagen/start.php',
    'leistungen' => __DIR__ . '/../vorlagen/leistungen.php',
    'kontakt'    => __DIR__ . '/../vorlagen/kontakt.php',
];

$wahl = is_string($_GET['seite'] ?? null) ? $_GET['seite'] : 'start';

if (!array_key_exists($wahl, $seiten)) {
    http_response_code(404);
    $wahl = 'start';
}

require $seiten[$wahl];
```

Ez a minta rövid, könnyen ellenőrizhető, és nem hagy mozgásteret. A modern keretrendszerekben az útválasztó (router) veszi át ezt a feladatot; ott a vezérlőket és a sablonokat sem szabad szabad paraméterekből meghatározni.

## Ha a fájlneveknek dinamikusnak kell lenniük: realpath és alapkönyvtár

Néha egy rögzített lista nem praktikus, például egy dokumentummappából való letöltéseknél. Ekkor a feloldott útvonalat ellenőrizze egy rögzített alapkönyvtárral szemben, és csak egyszerű fájlneveket engedjen meg.

```php
<?php
declare(strict_types=1);

const BASIS = '/var/www/daten/dokumente';

function sichererPfad(string $name): string
{
    if (!preg_match('/^[a-z0-9_-]{1,64}\.pdf$/', $name)) {
        throw new InvalidArgumentException('Ungültiger Dateiname.');
    }

    $basis = realpath(BASIS);
    $pfad  = realpath($basis . DIRECTORY_SEPARATOR . $name);

    if ($basis === false || $pfad === false
        || !str_starts_with($pfad, $basis . DIRECTORY_SEPARATOR)) {
        throw new RuntimeException('Datei nicht gefunden.');
    }

    return $pfad;
}

// Kiszolgálás beépítés helyett: a readfile() nem hajt végre kódot.
$datei = sichererPfad((string) ($_GET['datei'] ?? ''));
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . basename($datei) . '"');
readfile($datei);
```

Két pont döntő. A reguláris kifejezés nem enged könyvtárelválasztókat és speciális karaktereket. A csak kiszolgálandó fájlokat pedig `readfile()`-lal olvassák, nem `include`-dal, hogy a bennük lévő kód soha ne kerüljön végrehajtásra. Az `str_starts_with()` a PHP 8.0-tól érhető el.

## Szerveroldali védelem: php.ini, open_basedir és jogok

A biztonságos kód az első védvonal. A szerverkonfiguráció gondoskodik arról, hogy egy átnézett hiba kevesebb kárt okozzon.

```ini
; php.ini vagy FPM-pool (php_admin_value / php_admin_flag)
allow_url_include = Off
allow_url_fopen   = Off   ; csak ha az alkalmazás nem tölt be külső URL-eket
open_basedir      = /var/www/kunde-a/:/tmp/kunde-a/
display_errors    = Off
log_errors        = On
```

Az `allow_url_fopen`-re egyes alkalmazásoknak frissítésekhez vagy interfészekhez szükségük van. A kikapcsolást először egy tesztkörnyezetben próbálja ki. Az `open_basedir` a PHP-t a weboldal saját könyvtáraira korlátozza, ami különösen fontos több ügyfelet kiszolgáló szervereken. A részleteket az [open_basedir és weboldalankénti elkülönítés](https://phpsos.de/hu/ratgeber/open-basedir/) és a [A php.ini biztonságos beállítása](https://phpsos.de/hu/ratgeber/php-ini-sicher-konfigurieren/) útmutatók tartalmazzák.

Kiegészítésként a feltöltési és gyorsítótár-könyvtárak ne legyenek futtathatók, a naplófájlok pedig ne a webgyökérben legyenek. Így a támadónak hiányoznak azok a helyek, ahol saját tartalmat helyezhetne el egy beépítéshez.

## Miről ismeri fel a kihasználási kísérleteket a naplókban

A File Inclusion kihasználására tett kísérletek többnyire nyomot hagynak az access-naplóban. Feltűnőek a könyvtárváltásokat, abszolút rendszerútvonalakat, stream wrappereket vagy teljes idegen címeket tartalmazó paraméterek, különösen az olyan paramétereknél, mint a `page`, a `file`, a `template` vagy a `lang`. Egyetlen találat többnyire automatizált szkennelés. Fontos, hogy egy ilyen kérésre 200-as státuszkóddal és szokatlan válaszmérettel válaszoltak-e.

Hogyan járjon el ennél módszeresen, azt a [Webszerver-naplók kiértékelése egy támadás után](https://phpsos.de/hu/ratgeber/logfiles-auswerten/) írja le. Ha sikeres hozzáférések nyomára bukkan, feltételezze, hogy konfigurációs fájlokat olvastak, és újítsa meg a bennük lévő hozzáférési adatokat.

Ide tartoznak mindenekelőtt az adatbázis-jelszavak, a fizetési és szállítási szolgáltatók kulcsai, az SMTP-hozzáférések és a CMS titkos kulcsai. Ellenőrizze emellett, hogy az első gyanús hozzáférés óta keletkeztek-e új fájlok. Aki fájlokat tudott olvasni, az esetleg saját fájlokat is megpróbált elhelyezni. Ebben az esetben már nem csak a kódban lévő résről van szó, hanem egy biztonsági incidensről, amelyet strukturáltan kell kezelni.

### A javítások tartós biztosítása

Egy javítás után érdemes a védelmi funkciót automatizált tesztekkel biztosítani. Egy egyszerű teszt ismeretlen értékeket, könyvtárváltásokat és üres bemeneteket ad át az oldalválasztásnak, és minden esetben az alapértelmezett oldalt vagy egy 404-es hibát vár. Az ilyen tesztek megakadályozzák, hogy egy későbbi módosítás észrevétlenül ismét megnyissa a rést.

A vezetőség és a projektfelelősök számára hasznos egy kérdés az ügynökséghez: vannak-e az alkalmazásban olyan helyek, ahol fájlokat paraméterek alapján töltenek be, és hogyan vannak védve? Egy konkrét válasz lelőhelyekkel és tesztekkel jó jel.

## Hogyan segít konkrétan a PHP SOS?

- Célzottan keresünk a kódjában `include`, `require` és olyan fájlfüggvények után, amelyek a kérésből származó bemeneteket használnak, és minden leletet értékelünk.
- Weboldalanként beállítjuk az `allow_url_include`, az `open_basedir` értékét és a megfelelő jogokat, és ellenőrizzük, hogy az alkalmazás ezután is működik.
- Kiértékeljük a naplókat kihasználási kísérletek szempontjából, és tisztázzuk, hogy meg kell-e újítani a hozzáférési adatokat.
- Független ellenőrzéshez PHP-alkalmazásokra [biztonsági auditot penetrációs teszttel](https://phpsos.de/hu/leistungen/sicherheitsaudit-penetrationstest/) kínálunk.


## Gyakori kérdések

**Mi a különbség az LFI és az RFI között?**  
A Local File Inclusionnél az alkalmazás olyan fájlt tölt be, amely már a szerveren van, de nem kellene betöltenie. A Remote File Inclusionnél idegen címről töltenek be kódot. Az RFI nem biztonságos PHP-beállítást feltételez, az LFI nem.

**Elég a ../ eltávolítása a paraméterből?**  
Nem. Az ilyen szűrők gyakran megkerülhetők kódolással vagy változatokkal, és elkerülik a figyelmüket az abszolút útvonalak. Biztonságos csak az engedélyezett értékek rögzített hozzárendelése fájlokhoz, vagy a feloldott útvonal ellenőrzése egy alapkönyvtárral szemben.

**Teljesen véd az open_basedir a file inclusion ellen?**  
Nem, csak azokat a könyvtárakat korlátozza, amelyekhez a PHP hozzáférhet. Ezeken a határokon belül a rés kihasználható marad. Az open_basedir további védelmi réteg, és nem pótol biztonságos kódot.

**Érintettek az olyan CMS-ek, mint a WordPress az LFI-ben?**  
Az elterjedt CMS-ek magja ebből a szempontból jól ellenőrzöttnek számít. Rések inkább a bővítményekben, témákban és saját fejlesztésekben bukkannak fel. A bővítmények frissítései és biztonsági közleményeik áttekintése ezért fontos.

## Források

- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [BSI IT-Grundschutz (német Szövetségi Információbiztonsági Hivatal)](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
