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.