# Prevenire la local file inclusion in PHP: LFI e RFI

> Prevenire la local file inclusion in PHP: elenchi di consentiti invece di percorsi dalla richiesta, realpath, allow_url_include off e open_basedir.

Fonte: https://phpsos.de/it/ratgeber/lfi-rfi/  
Stato: 25/10/2026  
Fornitore: PHP SOS, Assistenza di emergenza PHP e sicurezza dei server. Assistenza immediata su WhatsApp: https://wa.me/491736494914?text=Buongiorno%20PHP%20SOS%2C%20abbiamo%20bisogno%20di%20aiuto%20con%20il%20nostro%20server%20PHP.%20Azienda%3A%20%E2%80%A6%20Sito%20web%3A%20%E2%80%A6

**In breve:** la local file inclusion in PHP nasce quando `include`, `require` o funzioni sui file usano un percorso che il visitatore può influenzare. La soluzione sicura è un elenco fisso di consentiti: il parametro sceglie solo tra valori noti, il percorso stesso non viene mai dalla richiesta. Lato server completano la protezione `allow_url_include=Off`, `open_basedir` e permessi dei file restrittivi.

## Che cos'è la local file inclusion in PHP?

Molte vecchie applicazioni PHP caricano le pagine con uno schema semplice: un parametro nell'indirizzo determina quale file viene incluso. Se questo parametro viene passato senza verifica a `include`, un aggressore può richiedere altri file sul server. Nel caso più innocuo legge file di configurazione con le credenziali. Nel caso peggiore induce PHP a eseguire contenuti che aveva depositato prima altrove, ad esempio in un upload o in un file di log.

Per la direzione è importante: questa vulnerabilità si trova di rado nel core del CMS, ma di solito in sviluppi propri, vecchie estensioni o pagine aggiuntive costruite in fretta. Nella quotidianità non salta all'occhio, perché il sito funziona normalmente.

Nella **remote file inclusion** PHP carica codice da un indirizzo esterno. Ciò presuppone che `allow_url_include` sia attivato. Nelle versioni attuali di PHP questa impostazione è disattivata per impostazione predefinita, ma su server vecchi o configurati male la si trova ancora.

### Schemi vulnerabili tipici nel codice

Sono a rischio i punti in cui un valore della richiesta, dei cookie o del database diventa parte di un percorso di file. Esempi frequenti sono i selettori di lingua che caricano un file di lingua in base a un parametro, la selezione delle pagine tramite un parametro nell'indirizzo, la scelta di template o temi e gli script di download per documenti. Un `.php` aggiunto alla fine del percorso non protegge in modo affidabile, perché gli aggressori possono ripiegare su file PHP esistenti.

Un primo quadro lo ottiene con una ricerca delle inclusioni che contengono variabili. Restituisce anche riscontri innocui, ma mostra dove guardare con più attenzione:

```bash
grep -rnE --include='*.php' '(include|require)(_once)?\s*\(?\s*\$' /var/www/projekt \
  | grep -v '/vendor/'
```

Controlli per ogni riscontro da dove proviene la variabile e se un visitatore possa influenzarla.

## Lo schema sicuro: elenco di consentiti invece di un percorso dalla richiesta

La protezione più affidabile è che il visitatore scelga solo una chiave e che sia l'applicazione a decidere quale file le corrisponda. Il percorso non viene mai composto da input.

```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];
```

Questo schema è breve, facile da verificare e non lascia margini. Nei framework moderni se ne occupa il router; anche lì controller e template non dovrebbero mai essere determinati da parametri liberi.

## Quando i nomi dei file devono essere dinamici: realpath e directory di base

A volte un elenco fisso non è praticabile, ad esempio per i download da una cartella di documenti. Allora verifichi il percorso risolto rispetto a una directory di base fissa e consenta solo nomi di file semplici.

```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;
}

// Consegnare invece di includere: readfile() non esegue codice.
$datei = sichererPfad((string) ($_GET['datei'] ?? ''));
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . basename($datei) . '"');
readfile($datei);
```

Due punti sono decisivi. L'espressione regolare non consente separatori di directory né caratteri speciali. E i file che devono solo essere consegnati vengono letti con `readfile()`, non con `include`, così che il codice eventualmente contenuto non venga mai eseguito. `str_starts_with()` è disponibile da PHP 8.0.

## Protezione lato server: php.ini, open_basedir e permessi

Il codice sicuro è la prima linea di difesa. La configurazione del server fa sì che un errore trascurato causi meno danni.

```ini
; php.ini o pool FPM (php_admin_value / php_admin_flag)
allow_url_include = Off
allow_url_fopen   = Off   ; solo se l'applicazione non carica URL esterni
open_basedir      = /var/www/kunde-a/:/tmp/kunde-a/
display_errors    = Off
log_errors        = On
```

`allow_url_fopen` serve ad alcune applicazioni per aggiornamenti o interfacce. Provi la disattivazione prima in un ambiente di test. `open_basedir` limita PHP alle directory proprie del sito, il che è particolarmente importante sui server con più clienti. I dettagli si trovano nelle guide [open_basedir e isolamento per sito](https://phpsos.de/it/ratgeber/open-basedir/) e [Configurare php.ini in modo sicuro](https://phpsos.de/it/ratgeber/php-ini-sicher-konfigurieren/).

In aggiunta, le directory di upload e di cache non dovrebbero essere eseguibili e i file di log non dovrebbero trovarsi nella webroot. Così a un aggressore mancano i luoghi in cui potrebbe depositare contenuto proprio per un'inclusione.

## Come riconoscere nei log i tentativi di sfruttamento

I tentativi di sfruttare una file inclusion lasciano di solito tracce nell'access log. Sono sospetti i parametri che contengono cambi di directory, percorsi assoluti di sistema, stream wrapper o indirizzi esterni completi, in particolare con parametri come `page`, `file`, `template` o `lang`. Un singolo riscontro è di solito una scansione automatizzata. Conta se una simile richiesta abbia ricevuto risposta con codice di stato 200 e dimensione della risposta insolita.

Come procedere in modo sistematico è descritto in [Analizzare i log del server web dopo un attacco](https://phpsos.de/it/ratgeber/logfiles-auswerten/). Se trova indizi di accessi riusciti, parta dal presupposto che i file di configurazione siano stati letti e rinnovi le credenziali in essi contenute.

Ne fanno parte soprattutto password del database, chiavi per servizi di pagamento e di spedizione, accessi SMTP e le chiavi segrete del CMS. Controlli inoltre se dal primo accesso sospetto siano comparsi nuovi file. Chi poteva leggere file potrebbe aver tentato anche di depositarne di propri. In questo caso non si tratta più solo di una vulnerabilità nel codice, ma di un incidente di sicurezza da gestire in modo strutturato.

### Rendere le correzioni durature

Dopo una correzione conviene proteggere la funzione di protezione con test automatizzati. Un semplice test passa alla selezione delle pagine valori sconosciuti, cambi di directory e input vuoti e si aspetta in tutti i casi la pagina predefinita o un errore 404. Tali test impediscono che una modifica successiva riapra la vulnerabilità senza che nessuno se ne accorga.

Per la direzione e i responsabili di progetto è utile una domanda all'agenzia: nell'applicazione ci sono punti in cui i file vengono caricati in base a parametri e come sono protetti? Una risposta concreta con i punti in cui si trovano e i test è un buon segno.

## Come aiuta concretamente PHP SOS?

- Cerchiamo nel Suo codice in modo mirato `include`, `require` e funzioni sui file con input dalla richiesta e valutiamo ogni ritrovamento.
- Impostiamo `allow_url_include`, `open_basedir` e permessi adatti per ogni sito e verifichiamo che l'applicazione continui a funzionare.
- Analizziamo i log alla ricerca di tentativi di sfruttamento e chiariamo se le credenziali debbano essere rinnovate.
- Per una verifica indipendente offriamo un [audit di sicurezza con penetration test](https://phpsos.de/it/leistungen/sicherheitsaudit-penetrationstest/) per applicazioni PHP.


## Domande frequenti

**Qual è la differenza tra LFI e RFI?**  
Nella local file inclusion l'applicazione carica un file che si trova già sul server ma che non dovrebbe essere caricato. Nella remote file inclusion il codice viene caricato da un indirizzo esterno. RFI presuppone un'impostazione PHP non sicura, LFI no.

**Basta rimuovere ../ dal parametro?**  
No. Simili filtri si aggirano spesso con codifiche o varianti e trascurano i percorsi assoluti. È sicura solo un'assegnazione fissa di valori consentiti a file oppure un controllo del percorso risolto rispetto a una directory di base.

**open_basedir protegge completamente dalla file inclusion?**  
No, limita soltanto le directory a cui PHP può accedere. All'interno di quei limiti una vulnerabilità resta sfruttabile. open_basedir è un livello di protezione aggiuntivo e non sostituisce un codice sicuro.

**I CMS come WordPress sono interessati da LFI?**  
Il core dei CMS diffusi è considerato ben verificato su questo punto. Le vulnerabilità compaiono piuttosto in estensioni, temi e sviluppi propri. Gli aggiornamenti delle estensioni e uno sguardo ai loro bollettini di sicurezza sono quindi importanti.

## Fonti

- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [BSI IT-Grundschutz (protezione di base IT del BSI)](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
