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

29

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

Queste sono le cose che faccio quando gli utenti inviano i dati:

  1. substr se sono stati trovati valori troppo limitati.
  2. htmlspecialchars() + ent_quotes + UTF-8
  3. str_replace '<' '>' gli utenti inseriscono

Quali altre cose devono essere fatte?

    
posta user2615947 16.09.2013 - 17:08
fonte

4 risposte

45

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

  1. Uscita in uscita. Questa è una preoccupazione dello stadio di uscita . Quando si prendono stringhe variabili e le si inseriscono in una stringa più grande con una sintassi circostante, è necessario elaborare la stringa inserita per renderla conforme ai requisiti di tale sintassi. Che cosa esattamente quell'elaborazione dipende dal contesto: se stai inserendo del testo in HTML, devi eseguire l'escape in formato HTML al punto di creare l'HTML. Se si inserisce del testo nelle query SQL, è necessario eseguire l'escape di SQL del testo al momento della creazione della query. (*)

  2. Convalida dell'input. Questa è una preoccupazione dello input-stage , assicurandosi che l'input dell'utente sia all'interno dei valori possibili accettati per un elemento di dati. Questa è principalmente una questione di regole aziendali, da considerare in base al campo, sebbene ci siano alcuni tipi di convalida che ha senso fare su 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 con l'escape dell'output. Ma non è sufficiente basarsi sulla convalida dell'input come unica misura di gestione del testo, perché è sempre necessario consentire all'utente di utilizzare alcuni caratteri che sono speciali nella sintassi alcuni o nell'altro. Dovrai essere in grado di avere una pagina web su fish & chips e un cliente nel tuo database chiamato O'Reilly .

"Sanificazione" confonde questi due concetti e ti incoraggia ad affrontarli nello stesso stadio, che non può mai funzionare in modo coerente. Un anti-pattern comune è quello di sfuggire HTML a tutti i tuoi input. Ma non si sa se ogni elemento di input verrà stampato in HTML (e solo in HTML) in quella fase di elaborazione dell'input. Se lo fai:

  • si finisce con materiale con codifica HTML nel database, che non può essere tagliato ed elaborato senza che i riferimenti all'entità si intromettano;

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

  • se ottieni contenuto nel tuo database da qualsiasi altra fonte potrebbe non essere in formato HTML-escape e quindi l'output diretto alla pagina ti dà ancora vulnerabilità XSS.

"Sanificazione" come concetto dovrebbe essere distrutto dal fuoco, quindi annegato, tagliato a pezzetti e distrutto da un altro fuoco ancora.

(*: in entrambi i casi è più saggio scegliere un metodo che esegue l'elaborazione in modo implicito in modo da non sbagliare: utilizzare un linguaggio di template HTML che sfugge all'output per impostazione predefinita e un livello di accesso ai dati che utilizza Analogamente per altri tipi di escape: preferire un serializzatore XML conforme agli standard per l'escape manuale XML, utilizzare un serializzatore JSON standard per passare dati a JavaScript e così via.)

substr if over limited values found.

Vuoi dire troncare stringhe di input troppo lunghe? Va bene come forma di convalida dell'input in cui le regole aziendali hanno validi motivi per limitare la lunghezza di un input. Ma potresti preferire di restituire un errore all'utente se hai una stringa di input troppo lunga, poiché a seconda del campo in cui si trova potrebbe non essere appropriato ignorare i dati in modo silenzioso.

htmlspecialchars() + ent_quotes + UTF-8

Questo è l'escaping dell'output. Fatelo sui valori al punto in cui li trascinate in HTML, non in input. Se stai utilizzando il PHP nativo per la creazione di modelli, potresti voler definire un collegamento per renderlo più veloce da digitare, ad esempio:

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

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

str_replace < > users input

Per cosa? Se si sta eseguendo l'escape dell'HTML correttamente, questi caratteri sono perfettamente validi e, a meno che le proprie regole aziendali non siano valide, possono essere abbastanza validi da includere in un campo, proprio come entrambi i caratteri sono validi per scrivere questa casella di commento per SO. p>

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

    
risposta data 16.09.2013 - 22:11
fonte
13

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

link

Il codice sorgente è altamente leggibile. Ci sono un sacco di lezioni dolorose lì dentro.

    
risposta data 23.09.2014 - 15:34
fonte
3

Poiché si tratta di un problema risalente a diversi anni fa, alcune cose cambiano e i link esterni generalmente si piegano in quanto i siti non gestiscono o indirizzano i collegamenti che potrebbero esistere in altri siti.

Quindi andando avanti, PHP è passato un po 'e molte persone chiedono informazioni sulla disinfezione degli input, ma l'uso di filter_var è sottile sul terreno, mentre non perfetto è dalla mia lettura, binario sicuro.

Quindi ottieni un indirizzo email, bene a meno che non usi HTML5 quando dovresti usarlo in combinazione con PHP filter_var , il tuo sito sarà più sicuro di chi scrive una routine per disinfettare un input che non lo fa t utilizzare input HTML5. Scrivere codice per la compatibilità a ritroso per i browser non conformi a HTML5 è completamente inutile e uno spreco di risorse e tempo.

L'altro problema di sicurezza è che i valori di $ _GET e $ _POST sono volatili e possono essere modificati o modificati esternamente da dati validi a dati non validi, pertanto qualsiasi routine di sanitizzazione che li utilizza e restituisce input puliti in essi è appena maturato per i guai ... L'array $ _REQUEST è più sicuro, una volta impostato nel tuo array sicuro, non può essere modificato, quindi popola il tuo array sicuro prendendo input e amp; filter_var li inserisce nell'array sicuro.

Come faccio a 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 (dai tasti) e gli input sterilizzati verranno quindi inseriti nei valori di quelle chiavi nell'array sicuro.

Questo significa che io uso le chiavi di una white-list (array) per SOLO prendere gli input che ho designato come campi validi. Troppe persone ho visto offrire processori "dinamici" che accettano NESSUN contributo, NO !!! Devi accettare solo i flussi di dati che il tuo codice / modulo è progettato per gestire.

SALE la tua pagina con un valore che il tuo modulo di ricezione può ricalcolare l'hashing corretto per verificare che il tuo modulo sia stato emesso dal server, campi EMPTY, includo almeno un firld vuoto che è readonly, nascosto come i campi hash ma l'intenzione è per determinare se il modulo è stato inserito o meno, un bot riempirà tutti i campi con i dati per provare a decifrare la pagina aperta.

SO Adescando 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 entrambi gli input, puoi anche cessare qualsiasi elaborazione dei moduli e registrare l'IP dell'utente e bloccarli in quanto sono un bot o un hacker.

L'iniezione non è solo un problema SQL, è un problema di pagina PHP, quindi stai attento a quali campi accetti, a cosa salt e bait del tuo modulo e gestisci una white-list.

STOP USANDO GET per passare i parametri di controllo, USA un cookie di sessione poiché questo riduce gli input allo 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 da provare e hackerare.

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

    
risposta data 13.11.2015 - 16:14
fonte
1

Personalmente non avrei mai str_replace su < e > , solo tag strip , html caratteri speciali , codifica delle entità html , < a href="http://php.net/mysql_real_escape_string"> mysql_real_escape_string ecc. sull'input dell'utente.

Ciò di cui hai bisogno è la modalità di rappresentazione dei dati?

  • Uscirà sul front-end?
  • Sta entrando nel database?
  • Sarà utilizzato in Javascript sul front-end?
  • Che ne dici dell'inclusione dei file?

Se sta entrando nel front-end, è necessario htmlentities it e strip_tags imo, in questo modo si può essere sicuri che non stiano tentando di eseguire alcun codice indesiderato.

Inoltre, la rimozione delle barre è una grande considerazione, recentemente ho catturato un XSS nel plugin SEO Platinum WP che è possibile eseguire il codice javascript attraverso il parametro $ _GET ['s'] codificando tutto in codice esadecimale-esadecimale (\ \ x41 = A).

Se inserisci dati nel database, dai un'occhiata alle domande preparate da PDO e mysql_real_escape_string . Questo dovrebbe proteggere gli input del tuo database abbastanza bene.

Se stai utilizzando l'input dell'utente per richiedere file, assicurati che non sia suscettibile agli attacchi Poison Null Byte e in la mia opinione, spoglia sempre tutte le barre sul file include, per garantire che non possano accedere alla posizione desiderata. Ti consigliamo inoltre di disattivare allow_url_include / allow_url_fopen nel tuo php.ini file.

Spero che questo aiuti!

    
risposta data 16.09.2013 - 17:20
fonte

Leggi altre domande sui tag