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.