2010-01-16 12 views
21

PIATTAFORMA: PHP & mySQLPHP & mySQL: quando utilizzare esattamente htmlentities?

Per i miei scopi di sperimentazione, ho provato alcune delle iniezioni XSS io stesso sul mio sito web. Considera questa situazione in cui ho inserito il mio modulo textarea. Poiché si tratta di un'area di testo, sono in grado di inserire testo e tutti i tipi di caratteri (inglesi). Ecco le mie osservazioni:

A). Se applico solo strip_tags e mysql_real_escape_string e non uso htmlentities sul mio input appena prima di inserire i dati nel database, la query si interrompe e sono colpito da un errore che mostra la struttura della mia tabella, a causa della terminazione anomala.

B). Se sto applicando strip_tags, mysql_real_escape_string e htmlentities sul mio input appena prima di inserire i dati nel database, , la query NON si sta interrompendo e sono in grado di inserire correttamente i dati dalla textarea nel mio database.

Quindi capisco che le risorse devono essere utilizzate a tutti i costi, ma non sono sicuro quando esattamente dovrebbe essere usato. Con in mente quanto sopra, vorrei sapere:

  1. Quando esattamente devono essere utilizzati htmlentities? Dovrebbe essere usato prima di inserire i dati nel DB o in qualche modo ottenere i dati in DB e quindi applicare htmlentities quando sto cercando di mostrare i dati dal DB?

  2. Se seguo il metodo descritto nel punto B) sopra (che credo sia la soluzione più ovvia ed efficiente nel mio caso), devo ancora applicare htmlentities quando sto cercando di mostrare i dati dal DB ? Se è così, perché? Se no, perché no? Lo chiedo perché è davvero fonte di confusione per me dopo Ho passato con la posta a: http://shiflett.org/blog/2005/dec/google-xss-example

  3. Poi c'è questa funzione un altro PHP chiamato: html_entity_decode. Posso usarlo per mostrare i miei dati dal DB (dopo aver seguito la mia procedura come indicato nel punto B) poiché htmlentities è stato applicato al mio input? Quale preferisco tra: html_entity_decode e htmlentities e quando?

ANTEPRIMA PAGINA:

ho pensato che potrebbe contribuire ad aggiungere alcuni dettagli più specifici di una situazione specifica qui. Considera che esiste una pagina di 'Anteprima'. Ora quando invio l'input da una textarea, la pagina di anteprima riceve l'input e lo mostra in html e allo stesso tempo, un input nascosto raccoglie questo input. Quando viene premuto il pulsante di invio sul pulsante Anteprima, i dati dall'input nascosto vengono POST su una nuova pagina e quella pagina inserisce i dati contenuti nell'input nascosto nel DB. Se non applico htmlentities quando il modulo è inizialmente inviato (ma si applicano solo strip_tags e mysql_real_escape_string) e c'è un input malevolo nella textarea, l'input nascosto è rotto e gli ultimi pochi caratteri dell'input nascosto sono visti visibilmente come " /> nella pagina , che è indesiderabile. Tenendo questo a mente, ho bisogno di fare qualcosa per preservare l'integrità dell'ingresso nascosto correttamente nella pagina di anteprima e ancora raccogliere i dati nell'input nascosto in modo che non si rompa. Come faccio a fare questo? Scusa per il ritardo nella pubblicazione di queste informazioni.

Grazie in anticipo.

+7

Solo un suggerimento: la maggior parte delle volte, non dovresti usare htmlentities, ma htmlspecialchars. htmlentities converte una tonnellata di caratteri, mentre htmlspecialchars converte solo quelli che DEVONO essere convertiti. –

+0

@ Michael Madsen: Grazie per il suggerimento. Il modulo accetta tutti gli input che è possibile inserire utilizzando una tastiera basata negli Stati Uniti. Quindi ho avuto questa idea che usare htmlentities lo renderà più sicuro, nel caso qualcuno provasse a copiare e incollare manualmente alcuni caratteri strani da qualche altro sito web o dal proprio sistema locale. Quindi ho deciso di usare htmlentities. Cosa ne pensi? – Devner

+1

Non ha senso. Sì, i personaggi strani potrebbero sembrare ... beh, strano sul tuo sito. Ma non lo stai evitando usando htmlentities, perché le entità sono solo un modo diverso di rappresentare lo stesso personaggio. Non hanno alcun significato speciale in HTML, quindi non c'è alcun vantaggio nel tradurli - il risultato finale sarà lo stesso, userà solo più byte per guardare in quel modo. –

risposta

51

Ecco la regola generale.

Variabili di escape su l'ultimo momento possibile.

Si desidera che le variabili siano rappresentazioni pulite dei dati. Cioè, se si sta cercando di memorizzare il cognome di qualcuno di nome "O'Brien", allora sicuramente non si desidera che questi:

O'Brien 
O\'Brien 

.. perchè, beh, questo non è il suo nome: non ci sono né commerciali né tagli. Quando si assume tale variabile e la si stampa in un contesto particolare (ad esempio: inserimento in una query SQL o stampa su una pagina HTML), è quando lo si modifica.

$name = "O'Brien"; 

$sql = "SELECT * FROM people " 
    . "WHERE lastname = '" . mysql_real_escape_string($name) . "'"; 

$html = "<div>Last Name: " . htmlentities($name, ENT_QUOTES) . "</div>"; 

Non si può mai desidera avere htmlentities stringhe -encoded memorizzati nel database. Cosa succede quando vuoi generare un file CSV o PDF o qualcosa che non sia codice HTML?

Mantieni i dati puliti e scappa solo per il contesto specifico del momento.

+1

Curioso, se c'è un elemento che non consente all'utente di usare alcun html, quindi si salva qualcosa come testo non-html in mysql, è ancora necessario usare htmlentities() quando lo si mostra? – JasonDavis

+0

definisce il testo non html? Qualche cosa considererebbe questo come HTML: 'pippo'. Considerano anche questo HTML: 'x z'. Se non si desidera che l'utente inserisca HTML, non trattare nulla di ciò che digita come HTML, ovvero salvarlo nel database verbatim e htmlentities quando viene visualizzato sullo schermo. – nickf

+0

Grazie per la risposta. Ho modificato il mio post originale per includere le informazioni che potrebbero essere utili per gettare un po 'di luce sulla situazione. Si prega di fare riferimento ad esso e inviare la vostra risposta. Grazie. – Devner

5

In pratica, è necessario utilizzare mysql_real_escape_string prima dell'inserimento del database (per impedire l'iniezione SQL) e quindi htmlentities, ecc. Nel punto di uscita.

Si desidera anche applicare il controllo di integrità a tutti gli input dell'utente per garantire (ad esempio) che i valori numerici siano effettivamente numerici, ecc. Funzioni come is_int, is_float, ecc. Sono utili a questo punto. (Vedi la sezione variable handling functions del manuale PHP per ulteriori informazioni su queste funzioni e altre simili.)

+0

@middaparka Grazie. Hai ragione. Ma stavo cercando di assicurarmi di poter essere al sicuro dagli attacchi CSS/XSS. La textarea accetta tutti i tipi di input, numerici, caratteri, ecc. In breve, accetta tutti gli input che è possibile inserire utilizzando una tastiera basata negli Stati Uniti. Quindi is_int, ecc. Non sono di grande aiuto in quanto sono ammessi anche altri tipi di input. Ho persino modificato il mio post originale per includere informazioni più specifiche. Si prega di fare riferimento ad esso e inviare la tua risposta come applicabile. Grazie mille. – Devner

5
  1. Solo prima si stampa il valore (non importa da DB o da $ _GET/$ _ POST) in HTML. htmlentities non ha nulla a che fare con il database.
  2. B è eccessivo. Dovresti mysql_real_escape_string prima di inserirlo in DB e htmlentities prima di stampare in HTML. Non è necessario mettere a nudo i tag, dopo htmlentities tag saranno visualizzati sullo schermo come < br /> ecc

Teoricamente si può fare htmlentities prima di inserire a DB, ma questo potrebbe fare ulteriori elaborazioni dei dati più difficile, se si avrebbe bisogno di un testo originale

3. See above 
+0

Secondo me non dovresti usare htmlentities prima di inserirlo nel DB. Non stai preservando i dati originali se lo fai –

+0

Sì, sto dicendo la stessa cosa. Ma se lo si vuole davvero, non costituirebbe un ulteriore rischio per la sicurezza, solo un po 'di ritardo. – BarsMonster

+0

@ d03boy: Grazie a entrambi per le risposte. Ho modificato il mio post originale per includere le informazioni che potrebbero essere utili per gettare un po 'di luce sulla situazione. Si prega di fare riferimento ad esso e inviare la vostra risposta. Grazie. – Devner

0

che ho passato questa prima e imparato due cose importanti:

Se stai ricevendo i valori da $ _POST/$ _ GET/$ _ richiesta e prevede di aggiungere alla DB, utilizzare la funzione mysql_real_escape_string per igienizzare i valori . Non li codifichi con htmlentities.

Perché non basta codificarli con htmlentities e inserirli nel database? Bene, ecco la cosa: l'obiettivo è rendere i dati quanto più significativi e puliti possibile e quando si codificano i dati con HTML come Jeff's Dog diventa Jeff & quot; s Dog ... che farà perdere significato al contesto dei dati . E se decidi di implementare servizi REST e recuperi quella stringa da DB e la metti in JSON, verrà fuori come Jeff & quot; s Dog che non è carina.Dovresti aggiungere un'altra funzione da decodificare. Supponiamo che tu voglia cercare "Jeff's Dog" usando SQL "select * dalla tabella dove field = 'Jeff \' s Dog '", non lo troverai perché "Jeff's Dog" non corrisponde "Jeff & quot; s Dog. " Cattivo, eh?

Per l'output di stringhe alfanumeriche (dal tipo CHAR) a una pagina Web, utilizzare htmlentities - SEMPRE!

+0

Grazie per il tuo commento. Sono d'accordo con te. Ho usato mysql_real_escape_string sin da quando i nostri amici lo hanno suggerito. Quindi, cosa suggerisci di utilizzare, htmlentities o htmlspecialchar per l'output di stringhe alfanumeriche (dal tipo CHAR, VARCHAR) a una pagina web? – Devner

Problemi correlati