Questo metodo di sanitizzazione è sicuro?

4

Ho implementato questa correzione per la sanitizzazione:

function san($str, $type="full") {
    switch ($type) {
        case "full":
            $str = preg_replace("/[^a-zA-Z0-9_\-]/i", "", $str);
        break;
        case "mid":
            $str = preg_replace("/</i", "&gt;", $str);
            $str = preg_replace("/>/i", "&lt;", $str);
        break;
        case "low":
            if ($str == "true" || $str == true)
                $str = true;
            else
                $str = false;
        break;
    }

Voglio dormire sonni tranquilli, ma non sono un esperto di sicurezza. Cosa può passare attraverso quel filtro? So usare la regex, ma è possibile codificare str per ignorare questa funzione?

Il livello mid è destinato alla protezione contro XSS e il livello full dall'iniezione di comandi, come questo:

$str = san($_REQUEST['cmd']);
$cmd = "cmd1 foo | cmd2 -arg=". $str; 
shell_exec($cmd); // is this secure?
    
posta David Sýkora 27.03.2016 - 18:00
fonte

1 risposta

7

Un filtro di input generico è sufficiente?

No, l'igienizzazione degli input non è la difesa adeguata contro qualsiasi attacco, quindi solo perché hai alcuni filtri non c'è motivo di chiamarlo un giorno.

Hai bisogno di difese adeguate contro gli attacchi tipici in atto, ad esempio istruzioni preparate per l'iniezione SQL, codifica delle variabili sull'output contro XSS, ecc.

Detto questo, il filtro di input aggiuntivo è altamente raccomandato come difesa in profondità.

Usabilità della tua funzione

L'usabilità è importante. Se nessuno sa cosa fa esattamente la tua funzione e come usarla correttamente, fornirà meno sicurezza in quanto le persone - questo potrebbe includerti in futuro - lo utilizzeranno in modo errato o lo modificheranno.

La tua funzione non è del tutto utilizzabile però. Se vedo san($x, "full") , non ho idea di cosa stia succedendo. Lo stesso vale per mid e low come argomenti (e il nome non sembra nemmeno avere senso, è basso dovrebbe essere meno sicuro - contro ... qualcosa ... - che pieno o medio?).

Un "full" generico rende anche molto facile cambiare il codice. Forse pensi che hai bisogno di ; in qualche altro caso, quindi perché non aggiungerlo? Non sembra fare alcun danno, e corrisponde ancora alla descrizione "completa".

Suggerirei una generica classe Input con metodi come getInt($name) , getAlphaNum($name) , getCleanHTML($name) , getRaw($name) , getFilter($name, $regex) , ecc. Con nomi come questi, vedi subito quello che ottieni e se è appropriato per l'input e la situazione. Sai anche di non cambiare l'implementazione ( getInt dovrebbe sempre restituire un intero, getAlphaNum sempre alfanum).

Difesa contro l'esecuzione di codice

Il tuo esempio dovrebbe essere sicuro. Non riesco ad uscire dal contesto corrente o aggiungere un nuovo comando, perché non ho né spazio né punto e virgola, né alcun altro carattere che possa essere usato in shell diverse per aggiungere nuovi comandi.

Ancora, come suggerito sopra, lo riscriverei. Quindi potrebbe apparire come questo:

$str = Input::getFilter("cmd", [^a-zA-Z0-9_\-]);
$cmd = "cmd1 foo | cmd2 -arg=". escapeshellarg($str); 
shell_exec($cmd); // is this secure?

Ora stai utilizzando l'approccio raccomandato (escapeshellarg) e disponi di un filtro aggiuntivo, in cui è abbastanza chiaro che cosa il filtro fa o potrebbe fare in futuro.

Difesa contro XSS

Prima di tutto, il tuo codice è bug. < è $lt (per meno di).

In secondo luogo, in alcuni casi questo difenderà dall'XSS, ma non da tutti. Non si difenderà dall'XSS se si è già in un contesto di tag (ad esempio <img src="[USERINPUT]"> ) o in un contesto JavaScript (ad esempio <script>var = "[USERINPUT]";</script> ).

Questo è anche uno dei motivi per cui il filtraggio degli input non è sufficiente per prevenire l'XSS (eccetto il filtraggio molto severo, ad esempio solo l'accettazione di un intero). Devi conoscere il contesto per difenderti adeguatamente. Nella maggior parte dei contesti, htmlspecialchars con ENT_QUOTES è comunque abbastanza buono, consulta questa guida per maggiori informazioni.

    
risposta data 27.03.2016 - 20:21
fonte

Leggi altre domande sui tag