2009-08-13 10 views
17

Mentre mi preparo ad affrontare il problema dell'input filtering e sanitization dei dati, sono curioso di sapere se esiste una pratica migliore (o più utilizzata)? È meglio filtrare/disinfettare i dati (di HTML, JavaScript, ecc.) Prima di inserire i dati nel database, o dovrebbe essere fatto quando i dati vengono preparati per la visualizzazione in HTML?Quando filtrare/disinfettare i dati: prima dell'inserimento del database o prima della visualizzazione?

Alcune note:

  • sto facendo questo in PHP, ma ho il sospetto la risposta a questo è il linguaggio agnostico. Ma se hai qualche consiglio specifico per PHP, per favore condividi!
  • Questo non è un problema di escape dei dati per l'inserimento del database. Ho già un PDO che sta gestendo abbastanza bene.

Grazie!

+0

Vedere la mia risposta a: http://stackoverflow.com/questions/129677/whats-the-best-method-for-sanitizing-user-input-with-php/130323#130323 – troelskn

risposta

17

Quando si tratta di visualizzare i dati inviati dall'utente, il mantra generalmente accettato è "Filtro input, uscita di uscita".

Prima di entrare nel database, sconsiglio di sfuggire a cose come entità html, ecc., Perché non si sa mai quando HTML non sarà il vostro mezzo di visualizzazione. Inoltre, diversi tipi di situazioni richiedono diversi tipi di escape dell'output. Ad esempio, l'incorporamento di una stringa in Javascript richiede un'escapezione diversa rispetto all'HTML. Fare questo prima potrebbe farti cullare in un falso senso di sicurezza.

Quindi, la regola di base è, disinfettare prima dell'uso e specificamente per tale uso; non preventivamente.

(Si noti che non sto parlando dell'output di escape per SQL, solo per la visualizzazione. Si prega comunque di eseguire l'escape dei dati associati a una stringa SQL).

+0

+1 Consiglio generale eccellente, in particolare il "mi raccomando di sfuggire a cose come entità html, ecc, prima di entrare nel database, perché non si sa mai quando HTML non sarà il vostro mezzo di visualizzazione" – Jeach

8

Mi piace avere/memorizzare i dati in forma originale. scappo/filtro i dati solo in base alla posizione in cui lo sto usando.

  • su una pagina web - codifica HTML
  • su SQL - uccidere citazioni
  • sulla url - urlencoding
  • su stampanti - fuga codificare comandi
  • su che cosa mai - codificare per quel lavoro
6

Sanitizzare per il database prima di inserirlo nel database, se necessario (cioè se non si sta utilizzando un livello di interattività del database che gestisce quello per voi). Disinfezione per la visualizzazione prima della visualizzazione.

Memorizzare le cose in una forma quotata attualmente inutile causa solo troppi problemi.

6

Ci sono almeno due tipi di filtro/sanificazione si dovrebbe preoccuparsi:

  • SQL
  • HTML

Ovviamente, il primo deve essere presa cura di prima/quando inserendo i dati nel database, per prevenire le Iniezioni SQL.
Ma tu lo sai già, come hai detto, quindi non ne parlerò più.


Il secondo, d'altra parte, è una domanda più interessante:

  • se gli utenti devono essere in grado di modificare i propri dati, è interessante tornare a loro allo stesso modo in cui l'ho inserito all'inizio; il che significa che devi memorizzare una versione "non-html-specialchars-escaped".
  • se si desidera visualizzare un codice HTML, è possibile utilizzare qualcosa come HTMLPurifier: molto potente ... Ma potrebbe richiedere un po 'troppe risorse se si esegue su tutti i dati quando deve essere visualizzato .. .

Quindi:

  • Se si desidera visualizzare il linguaggio HTML, utilizzando uno strumento pesante per validare/filtrarlo, direi che è necessario memorizzare una già filtrata qualsiasi versione/nel database , per non distruggere il server, ricrearlo ogni volta che vengono visualizzati i dati
    • ma è anche necessario per memorizzare la versione "originale" (vedere quello che ho detto prima)
    • In questo caso, probabilmente sarei memorizzare entrambe le versioni in banca dati, anche se ci vuole più posto ... O almeno usare un buon mecanismo del caching, per non ricreare più e più volte la versione pulita.
  • Se non si desidera visualizzare qualsiasi HTML, si utilizzerà htmlspecialchars o equivalente, che probabilmente non è che gran parte di una CPU-mangiatore ... Quindi probabilmente non importa molto
    • è ancora necessario memorizzare la versione "originale"
    • ma l'escaping quando si sta trasmettendo i dati potrebbe essere OK.

A proposito, la prima soluzione è anche bello se gli utenti utilizzano qualcosa come bbcode/Markdown/wiki quando si immettono i dati, e vi sono il rendering in HTML ...
Almeno, come a patto che venga visualizzato più spesso di quanto sia aggiornato, e specialmente se non si utilizza alcuna cache per memorizzare la versione HTML pulita.

+0

(Re: sanificare HTML in modo specifico) 8 anni dopo, ora che il rendering clientide è così comune, il "Direi che è necessario memorizzare una versione già filtrata/qualsiasi nel database, per non distruggere il server". Il punto qui è ora ancora più rilevante. La disinfezione dell'HTML è un'operazione costosa e in molti casi sarà più sensato disinfettare con il salvataggio anziché con la visualizzazione. Ci sono ovvi compromessi in termini di perdita dell'operazione e necessità di una migrazione dei dati per aggiornare le regole di sanitizzazione, ma ci sono molti casi in cui tali compromessi sono più che utili. –

3

Per lo più si dipende da che cosa avete intenzione di fare con l'ingresso, così come il vostro ambiente di sviluppo.

Nella maggior parte dei casi si desidera l'input originale. In questo modo hai il potere di modificare l'output a tuo piacimento senza paura di perdere l'originale. Ciò consente anche di risolvere problemi come l'output non funzionante. Puoi sempre vedere come i tuoi filtri sono difettosi o l'input del cliente è errato.

D'altra parte alcuni brevi dati semantici potrebbero essere filtrati immediatamente. 1) Non vuoi numeri di telefono disordinati nel database, quindi per tali cose potrebbe essere utile disinfettare. 2) Non vuoi che altri programmatori emettano dati accidentalmente senza fuggire, e lavori in ambiente multiprogrammer. Tuttavia, per la maggior parte dei casi i dati non elaborati sono meglio IMO.

5

Io dico sempre di scappare le cose immediatamente prima di trasferirle nel luogo in cui devono scappare. Il tuo database non si preoccupa dell'HTML, quindi l'escape dell'HTML prima di essere archiviato nel database non è necessario.Se vuoi pubblicare qualcosa di diverso dall'HTML, o modificare quali tag sono consentiti/non consentiti, potresti avere un po 'di lavoro davanti a te. Inoltre, è più facile ricordare di eseguire la fuga quando è necessario, piuttosto che in una fase molto precedente del processo.

Vale anche la pena notare che le stringhe con escape HTML possono essere molto più lunghe dell'input originale. Se inserisco un nome utente giapponese in un modulo di registrazione, la stringa originale potrebbe essere solo 4 caratteri Unicode, ma l'escape HTML può convertirlo in una lunga stringa di "& # 12345; & # 18784; & # 31337;" & # 31337; " . Quindi il mio nome utente di 4 caratteri è troppo lungo per il tuo campo di database, e viene memorizzato come due caratteri giapponesi più metà di un codice di escape, il che probabilmente mi impedisce anche di accedere.

Attenzione che i browser tendono a sfuggire ad alcune cose come -Il testo inglese nei moduli presentati stessi, e ci sarà sempre quella smartass che usa un nome utente giapponese ovunque. Quindi potresti volere effettivamente il codice unescape HTML prima di archiviare.

Problemi correlati