# Prevenirea Local File Inclusion în PHP: LFI și RFI

> Preveniți Local File Inclusion în PHP: liste de permisiuni în loc de căi din cerere, verificare realpath, allow_url_include dezactivat și open_basedir ca protecție.

Sursa: https://phpsos.de/ro/ratgeber/lfi-rfi/  
Stadiu: 25.10.2026  
Furnizor: PHP SOS, Asistență de urgență PHP și securitatea serverelor. Ajutor imediat pe WhatsApp: https://wa.me/491736494914?text=Bun%C4%83%20ziua%2C%20PHP%20SOS%2C%20avem%20nevoie%20de%20ajutor%20cu%20serverul%20nostru%20PHP.%20Firma%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Pe scurt:** Local File Inclusion în PHP apare când `include`, `require` sau funcțiile de fișiere folosesc o cale pe care vizitatorul o poate influența. Soluția sigură este o listă fixă de permisiuni: parametrul alege doar dintre valori cunoscute, calea însăși nu vine niciodată din cerere. Pe partea de server, `allow_url_include=Off`, `open_basedir` și drepturi restrictive ale fișierelor completează protecția.

## Ce este Local File Inclusion în PHP?

Multe aplicații PHP mai vechi încarcă paginile după un tipar simplu: un parametru din adresă stabilește ce fișier este inclus. Dacă acest parametru este transmis nevalidat către `include`, un atacator poate solicita alte fișiere de pe server. În cazul mai puțin grav, el citește fișiere de configurare cu date de acces. În cazul mai grav, face ca PHP să execute conținut pe care l-a depus înainte în altă parte, de exemplu într-o încărcare sau într-un fișier de log.

Pentru conducere este important: această vulnerabilitate se află rareori în nucleul CMS, ci de obicei în dezvoltări proprii, extensii vechi sau pagini suplimentare construite în grabă. Nu se observă în activitatea zilnică, deoarece site-ul funcționează normal.

La **Remote File Inclusion**, PHP încarcă cod de la o adresă străină. Aceasta presupune ca `allow_url_include` să fie activat. În versiunile PHP actuale, această setare este implicit dezactivată, dar pe servere vechi sau configurate greșit se mai întâlnește.

### Tipare vulnerabile tipice în cod

Sunt expuse locurile în care o valoare din cerere, din cookieuri sau din baza de date devine parte a unei căi de fișier. Exemple frecvente sunt comutatoarele de limbă care încarcă un fișier de limbă după un parametru, selecția paginilor printr-un parametru din adresă, alegerea șabloanelor sau a temelor și scripturile de descărcare pentru documente. Un `.php` atașat la sfârșitul căii nu protejează în mod fiabil, deoarece atacatorii pot recurge la fișiere PHP existente.

O primă imagine de ansamblu obțineți printr-o căutare a includerilor care conțin variabile. Ea livrează și rezultate inofensive, dar arată unde trebuie privit mai atent:

```bash
grep -rnE --include='*.php' '(include|require)(_once)?\s*\(?\s*\$' /var/www/projekt \
  | grep -v '/vendor/'
```

Verificați fiecare rezultat: de unde provine variabila și dacă un vizitator o poate influența.

## Tiparul sigur: listă de permisiuni în loc de cale din cerere

Cea mai fiabilă protecție este ca vizitatorul să aleagă doar o cheie, iar aplicația să decidă singură ce fișier îi corespunde. Calea nu este niciodată asamblată din date de intrare.

```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];
```

Acest tipar este scurt, ușor de verificat și nu lasă nicio marjă. În frameworkurile moderne, routerul preia această sarcină; și acolo, controlerele și șabloanele nu ar trebui niciodată stabilite din parametri liberi.

## Când numele fișierelor trebuie să fie dinamice: realpath și director de bază

Uneori o listă fixă nu este practică, de exemplu la descărcări dintr-un dosar de documente. Atunci verificați calea rezolvată față de un director de bază fix și permiteți doar nume simple de fișiere.

```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;
}

// Livrare în loc de includere: readfile() nu execută cod.
$datei = sichererPfad((string) ($_GET['datei'] ?? ''));
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . basename($datei) . '"');
readfile($datei);
```

Două puncte sunt decisive. Expresia regulată nu permite separatoare de directoare și nici caractere speciale. Iar fișierele care trebuie doar livrate sunt citite cu `readfile()`, nu cu `include`, pentru ca codul conținut să nu fie niciodată executat. `str_starts_with()` este disponibilă începând cu PHP 8.0.

## Securizarea pe partea de server: php.ini, open_basedir și drepturi

Codul sigur este prima linie de apărare. Configurarea serverului face ca o eroare ratată să provoace mai puțină pagubă.

```ini
; php.ini sau pool FPM (php_admin_value / php_admin_flag)
allow_url_include = Off
allow_url_fopen   = Off   ; doar dacă aplicația nu încarcă URL-uri externe
open_basedir      = /var/www/kunde-a/:/tmp/kunde-a/
display_errors    = Off
log_errors        = On
```

`allow_url_fopen` este necesar unor aplicații pentru actualizări sau interfețe. Testați dezactivarea mai întâi într-un mediu de test. `open_basedir` limitează PHP la directoarele proprii ale site-ului, ceea ce este deosebit de important pe serverele cu mai mulți clienți. Detalii găsiți în ghidurile [open_basedir și izolarea pe site](https://phpsos.de/ro/ratgeber/open-basedir/) și [Cum configurați php.ini în siguranță](https://phpsos.de/ro/ratgeber/php-ini-sicher-konfigurieren/).

În plus, directoarele de încărcări și de cache nu ar trebui să fie executabile, iar fișierele de log nu ar trebui să se afle în webroot. Astfel, atacatorului îi lipsesc locurile în care ar putea depune conținut propriu pentru o includere.

## Cum recunoașteți în loguri încercările de exploatare

Încercările de a exploata o file inclusion lasă de obicei urme în logul de acces. Sunt suspecți parametrii care conțin schimbări de director, căi absolute de sistem, wrappere de stream sau adrese străine complete, mai ales la parametri precum `page`, `file`, `template` sau `lang`. Un singur rezultat este de obicei scanare automatizată. Important este dacă o asemenea cerere a primit răspuns cu codul de stare 200 și o dimensiune neobișnuită a răspunsului.

Cum procedați sistematic descrie [Cum analizați logurile serverului web după un atac](https://phpsos.de/ro/ratgeber/logfiles-auswerten/). Dacă găsiți indicii ale unor accesări reușite, presupuneți că fișierele de configurare au fost citite și reînnoiți datele de acces conținute în ele.

Aici intră mai ales parolele bazei de date, cheile pentru serviciile de plată și de expediere, accesurile SMTP și cheile secrete ale CMS. Verificați, de asemenea, dacă de la primul acces suspect au apărut fișiere noi. Cine a putut citi fișiere a încercat poate și să depună unele proprii. În acest caz nu mai este vorba doar de o vulnerabilitate în cod, ci de un incident de securitate, care ar trebui tratat structurat.

### Securizarea durabilă a corecturilor

După o corectură merită să asigurați funcția de protecție cu teste automatizate. Un test simplu transmite selecției paginilor valori necunoscute, schimbări de director și date de intrare goale și așteaptă în toate cazurile pagina implicită sau o eroare 404. Asemenea teste împiedică o modificare ulterioară să redeschidă neobservat vulnerabilitatea.

Pentru conducere și responsabilii de proiect este utilă o întrebare către agenție: există în aplicație locuri în care fișierele sunt încărcate pe baza unor parametri și cum sunt securizate? Un răspuns concret, cu locurile găsite și cu teste, este un semn bun.

## Cum ajută PHP SOS concret?

- Căutăm țintit în codul dumneavoastră `include`, `require` și funcții de fișiere cu date de intrare din cerere și evaluăm fiecare constatare.
- Setăm `allow_url_include`, `open_basedir` și drepturi potrivite pentru fiecare site și verificăm că aplicația funcționează în continuare.
- Evaluăm logurile pentru încercări de exploatare și clarificăm dacă datele de acces trebuie reînnoite.
- Pentru o verificare independentă oferim un [audit de securitate cu test de penetrare](https://phpsos.de/ro/leistungen/sicherheitsaudit-penetrationstest/) pentru aplicațiile PHP.


## Întrebări frecvente

**Care este diferența dintre LFI și RFI?**  
La Local File Inclusion, aplicația încarcă un fișier care se află deja pe server, dar care nu ar fi trebuit încărcat. La Remote File Inclusion, codul este descărcat de la o adresă străină. RFI presupune o setare PHP nesigură, LFI nu.

**Este suficient să elimin ../ din parametru?**  
Nu. Asemenea filtre pot fi adesea ocolite prin codificare sau variante și ratează căile absolute. Sigure sunt doar o asociere fixă între valorile permise și fișiere sau o verificare a căii rezolvate față de un director de bază.

**Protejează open_basedir complet împotriva file inclusion?**  
Nu, limitează doar directoarele la care are voie să acceseze PHP. În interiorul acestor limite, o vulnerabilitate rămâne exploatabilă. open_basedir este un strat suplimentar de protecție și nu înlocuiește codul sigur.

**Sunt afectate de LFI CMS-uri precum WordPress?**  
Nucleul CMS-urilor uzuale este considerat bine verificat în această privință. Vulnerabilitățile apar mai degrabă în extensii, teme și dezvoltări proprii. Actualizările extensiilor și o privire în anunțurile lor de securitate sunt de aceea importante.

## Surse

- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [BSI IT-Grundschutz](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
