Ignora il filtro traversale di directory in PHP?

6

Ho un'app di PHP legacy, che ha un codice simile a questo:

<?php

$doc = $_GET['doc'];

if (preg_match('#\.\./#', $doc)) {
  header("HTTP/1.1 403 Forbidden");
  die();
}

$content = file_get_contents("/home/example/src/docs/" . $doc);

echo $content;

Il filtro mi sembra un po 'troppo semplicistico. Ho provato a lanciargli ogni sorta di attacchi e sembra fermarli. Qualcuno può pensare ad un modo per aggirare questo filtro?

    
posta Noodles 08.05.2016 - 23:30
fonte

3 risposte

2

È davvero troppo semplicistico. Puoi bypassarlo usando un carattere barra rovesciata. Esempio di un modo per aggirarlo sul mio server IIS: http://example.com/index.php?doc=..\/index.php

Controlla "../" mentre, per renderlo "più sicuro", dovrebbe cercare ".." o non consentire alcun punto e assicurarsi che sia incluso solo nell'estensione del file richiesto.

    
risposta data 09.05.2016 - 00:50
fonte
2

Anche se non riesco a pensare a qualcosa su un sistema Linux / POSIX diverso dalla fuga già descritta da Technidev, non voglio dire che non ce ne sia uno. Se fossi in me, mi sarei fidato del fatto che realpath () fosse in grado di gestire correttamente la semantica delle stringhe del percorso indipendentemente dal sistema operativo sottostante ....

$basedir="/home/example/src/docs/";
$target=realpath("/home/example/src/docs/" . $_GET['doc']);
if (substr($target, 0, strlen($basedir)) != $basedir || !file_exists($target)) {
   header("HTTP/1.1 403 Forbidden");
   exit -1;
}
    
risposta data 09.05.2016 - 13:41
fonte
1

Filtro input e amp; Bypassare

I filtri sono sempre ottimi come ulteriore livello di sicurezza, ma non dovrebbero essere la tua unica linea di difesa, perché generalmente i filtri mancano di contesto, rendendo impossibile il filtraggio sicuro al 100%.

Ad esempio, il filtro non sa nulla del sistema operativo sottostante. Accetta \ come separatore di directory? In tal caso, ..\ potrebbe funzionare. @Technidev ha menzionato un altro problema con ..\/ . A seconda del sistema operativo, anche altri attacchi potrebbero funzionare (ad esempio, potrebbe esserci un carattere che viene ignorato quando si trattano i percorsi, ma non durante il filtraggio, ho provato %00 come esempio, ma non funziona). Non ci dovrebbe essere un bypass generale che funzionerà indipendentemente dal sistema operativo.

Un filtro migliore, ma probabilmente troppo restrittivo, filtrerebbe per .. .

Difese appropriate

La tua domanda implicita sembra essere se questo codice è sicuro, o come renderlo più sicuro.

Se non hai bisogno di un percorso, utilizza basename , che restituirà un nome file.

Se hai bisogno di un percorso, ma dovrebbe essere all'interno della directory docs, risolvere il percorso e confrontarlo con il percorso di base .

    
risposta data 09.05.2016 - 11:14
fonte

Leggi altre domande sui tag