Escaping costanti JavaScript

7

come possono essere inclusi i valori non attendibili in una pagina html come costanti stringa javascript? Anche se il caso che sto chiedendo usa JSF e Rails, penso che questo sia un problema generale indipendente dal framework lato server.

on-attributi

Ovviamente non è sufficiente per uscire da \ "" in on-attributes:

onclick='alert("[variable]")'
variable: hello, world"); alert("XSS
result: alert("hello, world"); alert("XSS")

In Firefox questo mostrerà un "Ciao, mondo" e una finestra di dialogo di avviso "XSS". Poiché la variabile non contiene un ", la funzione Rails escape_javascript non è sufficiente in questo contesto. l'escape sembra essere sicuro, in quanto solo la finestra di dialogo originale è mostrata in questo caso:

result: onlick='alert("hello, world"); alert("XSS")'

Script-tag

In < script > i tag, tuttavia, in Firefox si applicano regole diverse:

<script type="text/javascript">
   alert("hello, world&quot;); alert(&quot;XSS");
</script>

Questo visualizza solo una finestra di dialogo; ma le virgolette sono visualizzate nella loro forma di escape. Ci sono due conclusioni: 1a) & quot; non è analizzato come un segno di virgolette JavaScript (buono), 2) non è analizzato in base alle regole HTML (male). In modo che qualsiasi tentativo di html di uscire dalla costante crei dati danneggiati.

Ignorare l'escaping HTML nei tag di script, tuttavia, non è un'opzione:

<script type="text/javascript">alert("[variable]");</script>
variable: hello, world</script><script>alert("XSS
result: <script type="text/javascript">
        alert("hello, world</script><script>alert("XSS");</script>

Il primo tag script crea un errore di sintassi a causa della mancanza ". Ma in Firefox viene eseguito il secondo tag script immesso.

tl, dr

C'è un modo sicuro per scrivere valori non affidabili per le costanti JavaScript? Questo sembra essere un casino totale, e al momento mi sto orientando verso l'uso di elementi html (con style="dispaly: none"). Una chiamata XMLHttpRequest che utilizza JSON sarebbe un'altra opzione. Ma entrambi gli approcci sembrano imbrogliare.

    
posta Hendrik Brummermann 23.12.2010 - 19:53
fonte

4 risposte

4

Se fossi su ASP.NET, ti consiglio di utilizzare MS WPL - il componente AntiXSS fornisce un .JavaScriptEncode () metodo, esattamente quello che ti serve.
Se fossi in JEE, ti avrei suggerito di utilizzare la libreria ESAPI di OWASP - anche lì c'è un. metodo encodeForJavaScript () (penso di averlo digitato correttamente, dalla memoria ...).
Purtroppo non ho familiarità con Rails abbastanza da fornire una soluzione per questo, ma forse OWASP ha qualcosa anche lì ... (EDIT: OWASP sta attualmente lavorando su una porta a Ruby, anche se non è ancora stato rilasciato ...)

Che cosa fanno entrambi questi metodi - codificano esplicitamente tutto che non è considerato un carattere "sicuro".
Che cosa fa non fa - le liste nere di determinati caratteri "cattivi", che dovrebbero essere costantemente aggiornati, dal momento che continua a essere aggirato.
Se necessario, dovresti essere in grado di hackerarlo anche in Rails, secondo la prima parte. MA non lo consiglierei, a meno che tu non sia assolutamente necessario.

    
risposta data 23.12.2010 - 23:44
fonte
6

Un'altra interessante (vecchia) libreria di codifica è OWASP Encoding Project (in precedenza la libreria "Reform") - link

Funzionalmente identico a Microsoft AntiXSS 1.x (non insolito - Mike Eddington ha scritto molte delle librerie interne di Microsoft che in seguito sono diventate AntiXSS e quindi WPL), ma supporta i linguaggi web più comuni tranne Ruby / Rails.

Implementa un approccio di codifica pessimistica (codifica tutto tranne quello che è noto per essere sicuro) e ti dà risultati come questo:

eval ('; - > eval \ x28 \ x27 \ x3b

eval \ u0080 - > eval \ u0080

\ u003cscript \ u003e. - > \ X3cscript \ X3e.

    
risposta data 27.12.2010 - 15:19
fonte
6

L'escape dell'HTML non è sufficiente negli attributi onclick se una delle proprietà di sicurezza si basa sul codice in esecuzione, ad es. un gestore onsubmit critico o un gestore di onload. Se un utente malintenzionato può incorporare il punto di codice U + 2028 o U + 2029, può causare l'interruzione dell'analisi, poiché non è consentito eseguire l'escape senza escape nelle stringhe JS.

Se hai a che fare con XHTML anziché HTML, e hai definito le tue% entità, queste sono sempre una via d'attacco, a meno che tu non sfugga anche a%, ma se stai usando XML, allora c'è meno di una differenza tra i corpi degli elementi di script e gli attributi.

    
risposta data 10.01.2011 - 13:49
fonte
5

Come hai notato, esistono almeno due contesti diversi, che richiedono regole di escape diverse: tag SCRIPT e valori di attributo contenenti Javascript. Piuttosto che cercare di trovare una risposta singola che funzioni per entrambi, dovresti cercare una soluzione diversa per ogni contesto. Commenterò principalmente le stringhe letterali all'interno dei tag SCRIPT.

Un modo semplice per codificare le costanti di stringa in Javascript consiste nell'assumere caratteri non sicuri e tradurli in escape Unicode: ad es., a - > %codice%. Suggerisco di creare una piccola whitelist di caratteri sicuri (a-z, A-Z, 0-9) e di codificare tutto il resto.

Ancora meglio sarebbe utilizzare una libreria standard e ben controllata per eseguire la fuga. Non ho una raccomandazione specifica, ma altri potrebbero averne uno. AntiXSS ha una buona reputazione e JavaScriptEncode sembra pertinente. Assicurati che sia appropriato per il particolare contesto in cui verrà inserita la stringa.

Insubori non ovvi:

  • Come hai notato, \u0061 può terminare un tag SCRIPT, anche quando si trova all'interno di una stringa quotata. Questo perché, quando il browser vede un tag aperto </SCRIPT> , il parser HTML del browser inizia a cercare un tag di <SCRIPT> di chiusura prima inizia a analizzare lo stesso JavaScript utilizzando il parser Javascript e un </SCRIPT> all'interno di una costante di stringa può chiudere prematuramente il tag SCRIPT. Pertanto, le parentesi angolari non sono sicure per apparire senza caratteri all'interno di una stringa letterale Javascript. Per ragioni analoghe, anche le e commerciali non sono sicure. (Ringrazio Adam Barth e Collin Jackson per avermi insegnato questa sottigliezza.)
  • È possibile utilizzare le virgolette per uscire da una stringa quotata, quindi le virgolette singole e doppie non sono sicure.
  • I backslash possono essere usati per uscire da una stringa quotata (immagina terminare con una </SCRIPT> ), e quindi non sono sicuri.
  • Se si utilizza JSON e si include un input utente non attendibile all'interno del nome di una proprietà (anziché del valore), le cose possono diventare complicate. Assicurati di citare il nome e applica le stesse regole come per gli altri valori letterali stringa. Inoltre, potrebbero essere necessari anche altri controlli (ad esempio, non consentire "valueOf", ecc.).
  • Fai attenzione al set di caratteri usato nella pagina HTML. UTF-7 può davvero rovinare la tua giornata . Suggerisco di trattare + e - come caratteri non sicuri e di garantire che la pagina includa un set di caratteri esplicito nell'intestazione HTTP Content-Type o in un tag META HTML (per ridurre al minimo la possibilità che il browser tenti di rilevare automaticamente il set di caratteri).
  • Fai attenzione a non scappare. La doppia escape può reintrodurre problemi di sicurezza, in alcuni casi.

Risorse utili: link , link . Inoltre, ti incoraggio a consultare Progetto e l'Interpolique di Dan Kaminsky, due metodi innovativi per affrontare questo tipo di problemi.

    
risposta data 07.01.2011 - 10:35
fonte

Leggi altre domande sui tag