Da giorni cerco di capire come scrivere un'applicazione web sicura in PHP, e risulta essere particolarmente difficile. Più leggo, più affondo in profonde paludi piene di vulnerabilità che non sono menzionate da persone gentili come Matt Robinson o Chris Shiflett .
Per alcuni esempi, prendi:
In breve, vedo i seguenti problemi:
- Quando si filtra l'input, non è molto chiaro in che modo i dati verranno decodificati successivamente, e quindi i sistemi di codifica e di escape dei caratteri possono bypassare il filtraggio degli input. (come la decodifica con doppio url)
- Durante l'escape dell'output, vengono utilizzate funzioni standard come htmlspecialchars . È bello che htmlspecialchars abbia un parametro di codifica, tuttavia ciò non impedisce di inviare input UTF-16 ad esso, e ciò potrebbe probabilmente rompere il valore di sicurezza della funzione.
Sembra che ci sia un modulo mbstring in php, ma se è vagamente sicuro quanto la documentazione è comprensibile, allora probabilmente sarà inutile anche se riuscirò a capire come usarlo. Solo un esempio dei documenti per l'illustrazione :
mbstring.strict_detection boolean
Enables the strict encoding detection.
Ottimo, è utile.
Sfortunatamente le funzioni dipendono anche da cosa hai impostato nelle opzioni di configurazione ... Sembra esserci una funzione chiamata mb_convert_encoding
, ma i documenti non dicono nulla sull'aspetto sicurezza e sembra che tu debba conoscere la codifica in ingresso (una zona di non sicurezza per la sicurezza). C'è anche mb_check_encoding
. Il che sembra essere pensato per la pulizia, ma leggere i commenti degli utenti sui documenti non ispira esattamente la fiducia.
Quindi la domanda è, alla luce di tutto ciò, come fai il filtraggio sicuro degli input ? Qualcosa di simile?
-
mb_convert_encoding
a utf-8 -
mb_check_encoding
per rifiutare l'input non valido - loop url_decode finché la stringa non smette di cambiare
- Esegui il normale filtraggio degli input con confronto e regex di testo, ecc ...
modifica: si noti che 3 è problematico perché il normale filtro di input potrebbe introdurre di nuovo entità che possono essere decodificate con URL
modifica
Ho trovato una risposta parziale qui , da Shiflett. Sembra che per htmlspecialchars che utilizza il suo parametro di codifica e assicurandosi di impostare l'intestazione di codifica dei caratteri per il browser sullo stesso, si eviti che il browser interpreti i caratteri in modo diverso rispetto a htmlspecialchars. Tutto ciò presuppone che l'input di htmlspecialchars sia valido per la codifica data o che per ogni possibile input non valido htmlspecialchars interpreti la stringa esattamente nello stesso modo di ogni browser. Sappiamo che se non troviamo alcun modo di sanificare il nostro input non possiamo garantire che l'input di htmlspecialchars sia codificato validamente, perché un utente malintenzionato potrebbe preparare una stringa con codifica non valida. Questo ci porta alla seconda possibilità, che htmlspecialchars si comporti come il browser identico per tutti i possibili input. Questo è un problema, dal momento che non possiamo usare lo stesso tokenizer per l'escape e l'utilizzo, dal momento che uno accade sul server e uno accade nel browser.
Questo è tutto simile a ciò che msql_real_escape fa per un database, anche se penso che tu possa risolvere correttamente questo problema per msql usando invece istruzioni preparate.
Un terzo output problematico è il filesystem quando si utilizza php per caricare file o altre manipolazioni del file system. A proposito di quest'ultimo sembra che ci siano pochissime informazioni disponibili. Non conosco nemmeno una funzione di escape specifica, per non parlare di una che è robusta quando riceve input distorti.