it-swarm-eu.dev

Qual è il modo migliore per disinfettare l'input dell'utente in PHP?

Qual è il modo migliore per disinfettare l'input dell'utente?

Queste sono cose che faccio quando gli utenti inviano dati:

  1. substr se sono stati rilevati valori limitati.
  2. htmlspecialchars() + ent_quotes + UTF-8
  3. str_replace '<' '>' input dell'utente

Quali altre cose devono essere fatte?

31
user2615947

"Sanificazione" è un termine inutile e fuorviante. Ci sono due diversi animali qui:

  1. Uscita in uscita. Questo è un preoccupazione della fase di output. Quando si prendono stringhe variabili e le si iniettano in una stringa più grande che ha una sintassi circostante, è necessario elaborare la stringa iniettata per renderla conforme ai requisiti di tale sintassi. Che cosa sia esattamente quell'elaborazione dipende dal contesto: se stai inserendo del testo in HTML, devi sfuggire a quel testo al punto di creare l'HTML. Se si inserisce testo nelle query SQL, è necessario eseguire l'escape SQL del testo al momento della creazione della query. (*)

  2. Convalida input. Questo è un preoccupazione della fase di input, assicurandosi che l'input dell'utente rientri nei valori possibili accettati per un elemento di dati. Questa è principalmente una questione di regole di business, da considerare campo per campo, anche se ci sono alcuni tipi di convalida che ha senso fare a quasi tutti i campi di input (controllando principalmente i caratteri di controllo).

La convalida dell'input ha un impatto sulla sicurezza in quanto può mitigare il danno quando si commette un errore durante la fuga dell'output. Ma non è sufficiente fare affidamento sulla convalida dell'input come unica misura di gestione del testo perché dovrai sempre consentire all'utente di utilizzare alcuni caratteri speciali nella sintassi alcuni o nell'altro. Avrai voglia di avere una pagina web su fish & chips e un cliente nel tuo database chiamato O'Reilly.

La "sanificazione" confonde questi due concetti e ti incoraggia ad affrontarli nella stessa fase, che non potrà mai funzionare in modo coerente. Un anti-pattern comune è quello di evitare l'HTML di tutti i tuoi input. Ma non sai se ogni elemento di input verrà generato in HTML (e solo output in HTML) in quella fase di elaborazione dell'input. Se lo fai:

  • si finisce con materiale codificato HTML nel database, che non può essere tagliato ed elaborato senza che i riferimenti alle entità si frappongano;

  • se hai bisogno di creare contenuti da quei dati che non sono HTML, come inviare un'e-mail o scrivere un CSV, hai un brutto testo maledetto in esso;

  • se ottieni contenuti nel tuo database da qualsiasi altra fonte, potrebbe non essere evaso da HTML e quindi inviarlo direttamente alla pagina ti dà ancora vulnerabilità XSS.

La "sanificazione" come concetto dovrebbe essere distrutta dal fuoco, quindi affogata, tagliata in piccoli pezzi e distrutta da un po 'più di fuoco.

(*: in entrambi i casi è più saggio scegliere un metodo che esegue implicitamente l'elaborazione per te, quindi non sbagli: usa un linguaggio di template HTML che sfugge all'output di default e un livello di accesso ai dati che utilizza query con parametri o mappatura relazionale agli oggetti Allo stesso modo per altri tipi di escape: preferisce un serializzatore XML conforme agli standard rispetto all'escaping manuale XML, usa un serializzatore JSON standard per passare i dati a JavaScript e così via.)

substr se sono stati trovati valori limitati.

Intendi troncare stringhe di input troppo lunghe? Va bene come una forma di convalida dell'input in cui le regole aziendali hanno motivi validi per limitare la lunghezza di un input. Ma potresti preferire la restituzione di un errore all'utente se hai una stringa di input troppo lunga, poiché a seconda di quale campo sia potrebbe non essere appropriato scartare silenziosamente i dati.

htmlspecialchars () + ent_quotes + UTF-8

Questo è l'output di escape. Fatelo sui valori nel punto in cui li rilasciate in HTML, non sull'input. Se stai usando native PHP potresti voler definire un collegamento per rendere più veloce la digitazione, ad esempio:

function h($s) {
    echo htmlspecialchars($s, ENT_QUOTES, 'utf-8')l
}
...

<p>Hello, <?php h($user['name']); ?>!</p>

str_replace <> input utenti

Per che cosa? Se stai eseguendo correttamente l'escaping dell'HTML, questi caratteri sono perfettamente a posto e, a meno che le tue regole aziendali non diano diversamente, potrebbero essere del tutto validi per essere inclusi in un campo, così come entrambi i caratteri sono validi per me in questa casella di commento per SO.

Ovviamente potresti volerli vietare nella convalida dell'input per campi specifici, non li vorrai in un numero di telefono.

49
bobince

Uso OWASP PHP. Sono davvero semplici da usare ed efficaci.

https://www.owasp.org/index.php/OWASP_PHP_Filters

Il codice sorgente è altamente leggibile. Ci sono molte lezioni dolorose lì dentro.

11
mgjk

Poiché questo è un problema di diversi anni fa, alcune cose cambiano e i collegamenti esterni generalmente si piegano poiché i siti non mantengono o indirizzano i collegamenti che potrebbero esistere in altri siti.

Andando avanti, PHP si è spostato un po 'e molte persone chiedono di disinfettare gli input, ma finora l'uso di filter_var è sottile sul terreno, anche se non perfetto per la mia lettura, binario sicuro.

Quindi ottieni un indirizzo e-mail, a meno che tu non usi HTML5 quando dovresti usarlo insieme a PHP filter_var, il tuo sito sarà più sicuro di chiunque scriva una routine per disinfettare un input che non utilizza input HTML5. Scrivere codice per la compatibilità con le versioni precedenti per browser non compatibili con HTML5 è completamente inutile e fa perdere tempo e risorse.

L'altro problema della sicurezza è che i valori di $ _GET e $ _POST sono volatili e possono cambiare o essere cambiati esternamente da dati buoni a dati cattivi, quindi qualsiasi routine di sanificazione che li utilizza e restituisce input puliti in essi è appena matura per guai ... $ _REQUEST array è più sicuro, una volta impostato nel tuo array sicuro, non può essere modificato, quindi popola il tuo array sicuro prendendo input e filtra_var nell'array sicuro.

Come disinfettare gli input è qualcosa di simile a ciò che segue ...

$someSafeArray = array(
        "thefield"=>FILTER_SANITIZE_STRING,
        "theNumberfield"=>FILTER_SANITIZE_NUMBER,
        "theEmailfield"=>FILTER_SANITIZE_EMAIL
        );
foreach( $someSafeArray as $fld=>&$val)
    $val = filter_var( trim( $_REQUEST[$fld] ), $val );

Quindi questo restituirà tutti i campi (dalle chiavi) e gli input disinfettati verranno quindi inseriti nei valori di quelle chiavi nella matrice sicura.

Ciò significa che uso i tasti di una lista bianca (array) per prendere SOLO gli input che desidero essere campi validi. Troppe persone che ho visto offrire processori di moduli "dinamici" che accettano QUALSIASI input, NO !!! Dovresti accettare solo flussi di dati che il tuo codice/modulo è progettato per gestire.

SALA la tua pagina con un valore che il tuo modulo di ricezione può ricalcolare l'hash corretto per verificare che il tuo modulo sia stato emesso dal server, campi EMPTY, includo almeno un firld vuoto che è di sola lettura, nascosto come campi di hashing ma l'intenzione è di determinare se il modulo viene inviato o meno, un bot riempirà tutti i campi con i dati per tentare di aprire la pagina.

Quindi attacca la tua pagina con un paio di campi fittizi come ...

<input name="userlogin" type="hidden" value="" readonly />
<input name="empty" type="hidden" value="" readonly />

se il modulo è arrivato sul tuo server con qualcosa nel campo del valore di uno dei due input, puoi anche interrompere l'elaborazione del modulo e registrare l'IP dell'utente e bloccarlo poiché sono un bot o un hacker.

L'iniezione non è solo un problema di SQL, è un problema PHP pagina, quindi stai attento a quali campi accetti, cosa salt e bait nel tuo modulo con e gestire una lista bianca.

FERMA DI UTILIZZARE GET per passare i parametri di controllo, UTILIZZARE un cookie di sessione in quanto riduce gli input nello script, Se utilizzo un URL di tipo GET, è solo per una tattica sovversiva e consente il monitoraggio degli utenti che inseriscono le variabili nell'URL e altre cose per provare a hackerare.

Ho usato un processo come questo da prima che fosse introdotta la funzione filter_var, stavo salando le pagine senza la necessità di un database per convalidare le pagine in arrivo ed era qualcosa che mi era stato ripetutamente detto dai cosiddetti professionisti non era possibile, beh il l'unica cosa che devo dire è che "è se si è in grado di pensare al di fuori della piastra della caldaia. (scatola)" e abbastanza semplice da contrastare i tentativi di hacking, proteggere le pagine del modulo.

4
Mark Giblin

Personalmente non vorrei mai str_replace su < e >, solo tag tag , caratteri speciali html , codifica entità html , mysql_real_escape_string ecc. sull'input dell'utente.

Quello che devi tenere in considerazione è come saranno rappresentati i dati?

  • Verrà emesso sul front-end?
  • Sta andando nel database?
  • Verrà utilizzato in Javascript sul front-end?
  • Che ne dici di includere i file?

Se sta andando nel front-end, allora devi htmlentities e strip_tags imo, in questo modo puoi essere sicuro che non stiano cercando di eseguire alcun codice indesiderato.

Inoltre, eliminare le barre è una grande considerazione, di recente ho scoperto un XSS nel plug-in Platinum SEO WP Platinum SEO che potresti eseguire codice javascript tramite il parametro $ _GET ['s'] codificando tutto in codice hex-escape (\\ x41 = A).

Se stai inserendo dati nel database, dai un'occhiata a Query preparate DOP e mysql_real_escape_string . Questo dovrebbe proteggere abbastanza bene gli input del tuo database.

Se stai utilizzando l'input dell'utente per richiedere i file, assicurati che non sia suscettibile agli attacchi Poison Null Byte e, a mio avviso, rimuovi sempre tutte le barre nei file inclusi, per assicurarti che non possano accedere alla posizione desiderato. Consiglierei anche di disattivare allow_url_include/allow_url_fopen nel tuo file php.ini.

Spero che questo possa essere d'aiuto!

0
DarkMantis