2012-05-01 15 views
7

Qual è il modo corretto di codificare i dati non attendibili per il contesto degli attributi HTML? Per esempio:PHP: codifica degli attributi HTML/decodifica JavaScript

<input type="hidden" value="<?php echo $data; ?>" /> 

Io di solito uso htmlentities() o htmlspecialchars() per fare questo:

<input type="hidden" value="<?php echo htmlentities($data); ?>" /> 

Tuttavia, di recente ho incontrato un problema in cui questa è stata la rottura la mia domanda, quando i dati che ho bisogno di passare era un URL che doveva essere consegnato fuori a JavaScript di cambiare la posizione della pagina:

<input id="foo" type="hidden" value="foo?bar=1&amp;baz=2" /> 
<script> 
    // ... 
    window.location = document.getElementById('foo').value; 
    // ... 
</script> 

In questo caso, foo è un programma C, e non capisce i caratteri codificati nell'URL e nei segoult.

Posso semplicemente prendere il valore in JavaScript e fare qualcosa come value.replace('&amp;', '&'), ma sembra kludgy e funziona solo per la e commerciale.

Quindi, la mia domanda è: c'è un modo migliore per fare la codifica o la decodifica dei dati che vengono iniettati in attributi HTML?

Ho letto tutto di OWASP's XSS Prevention Cheatsheet e mi sembra che fintanto che sto attento a citare i miei attributi, quindi l'unico carattere che ho bisogno di codificare è la citazione stessa (") - nel qual caso, I potrebbe usare qualcosa come str_replace('"', '&quot;', ...) - ma, non sono sicuro se sto capendo correttamente.

+2

Non urlencode prendersi cura di questo in PHP? Ci sono alcuni esempi di codice nei commenti che mostrano come proteggersi anche dall'XSS sul manuale php. http://php.net/manual/en/function.urlencode.php – GillesC

+0

@gillesc: 'urlencode()' è per encoding URL * parameters *, non interi URL e non codifica per il contesto dell'attributo HTML. C'è una sezione nel manuale che parla anche di questo - * "Lascia come &, ma semplicemente codifica i tuoi URL usando htmlentities() o htmlspecialchars()." * – FtDRbwLXw6

+0

sei sicuro di 'window.location = document.getElementById ('foo'); '? che dovrebbe essere così penso-> 'window.location = document.getElementById ('foo'). value;' e reindirizza alla pagina giusta (foo? bar = 1 & baz = 2) – ocanal

risposta

11

Il tuo attuale metodo di utilizzare htmlentities() o htmlspecialchars() è l'approccio giusto.

L'esempio che hai fornito è corretto HTML:

<input id="foo" type="hidden" value="foo?bar=1&amp;baz=2" /> 

La e commerciale del valore di attributo ha infatti bisogno da codificare HTML, altrimenti il ​​codice HTML non è valido. La maggior parte dei browser la analizza correttamente con uno &, ma ciò non cambia il fatto che non sia valido e che tu sia corretto per codificarlo.

Il tuo problema non sta nella codifica del valore, che è buono, ma nel fatto che stai usando il codice Javascript che non lo decodifica correttamente.

In effetti, sono sorpreso di questo, perché il tuo codice JS sta accedendo al DOM, e il DOM dovrebbe restituire i valori decodificati.

ho scritto una JSfiddle per dimostrare questo a me stesso: http://jsfiddle.net/qRd4Z/

L'esecuzione di questo, mi dà una finestra di avviso con il valore decodificato come mi aspettavo. La modifica a console.log fornisce anche il risultato che mi aspetto. Quindi non sono sicuro del motivo per cui ottieni risultati diversi? Forse stai usando un browser diverso? Potrebbe valere la pena di specificare con quale testare. O forse hai codificato le entità per errore? Puoi confermare che non è il caso?

0

È possibile utilizzare il DOM per decodificare il valore:

function decodeHTMLSpecialChars(input){ 
    var div = document.createElement('div'); 
    div.innerHTML = input; 
    return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue; 
} 

Questo renderà la seguente stringa:

'http://someurl.com/foo?bar=1&amp;baz=2' 

a questo:

decodeHTMLSpecialChars('http://someurl.com/foo?bar=1&amp;baz=2'); 
// => 'http://someurl.com/foo?bar=1&baz=2 

e non, per HTML codifica e decodifica, l'escape htmlspecialchars e html è il metodo standard e sta eseguendo il lavoro va bene per te

5

Qual è il modo corretto di codificare i dati non attendibili per il contesto dell'attributo HTML?

Se si aggiungono virgolette doppie attorno al valore dell'attributo, htmlspecialchars() è sufficiente.

<input id="foo" type="hidden" value="foo?bar=1&amp;baz=2" /> 

Questo è corretto, e il browser invierà foo?bar=1&baz=2 (decodificato &amp;) al server. Se il server non vede foo?bar=1&baz=2, è necessario aver codificato il valore due volte.

Ottenere il valore in javascript deve restituire foo?bar=1&baz=2 anche (ad esempio document.getElementById('foo').value deve restituire foo?bar=1&baz=2).

Visualizza l'origine della pagina utilizzando il browser e visualizza la sorgente effettiva del campo di input.

Se si modifica il valore del campo di input utilizzando Javascript, lo script deve essere codificato in modo doppio.

BTW il programma non dovrebbe SEGFAULT a causa di input dell'utente sbagliato;)

0

Si prega di notare che l'uso htmlentities come è doesn Aiuta!

Di default codifica solo " < > &

Non sfugge ' che può creare un problema!

Assicurarsi di utilizzare bandiere per le funzioni, è possibile trovare l'uso ed esempi here

+0

Grazie, ma ciò varrebbe solo se non si delimitarono correttamente i valori degli attributi con '' 'caratteri, e lo faccio. È una cattiva pratica escludere delimitatori o delimitare con' ''. – FtDRbwLXw6