Questa codifica JSON è vulnerabile all'iniezione CDATA?

2

Ho trovato una strana notazione nelle pagine generate da jsfiddle.net

<script type='text/javascript'>//<![CDATA[ 
$(window).load(function(){
$('form, table').animate({
    opacity: 1
});
});//]]>  

</script>

Talvolta nutro i dati JSON direttamente in uno script. Personalmente non uso la notazione CDATA, ma voglio confermare se un utente malintenzionato potrebbe iniettare la notazione CDATA e causare cose brutte.

Eseguo gli oggetti tramite un identificatore JSON standard che segue tutte le regole , quindi sostituisco </script con <\/script , Non sensibile a maiuscole e minuscole. È sufficiente?

    
posta George Bailey 26.01.2012 - 21:06
fonte

2 risposte

6

Il //<![CDATA[ hack viene utilizzato nelle pagine XHTML che devono analizzare sia come HTML sia come XML.

Nelle regole di analisi HTML, <script> e <style> sono speciali "elementi CDATA", i cui contenuti fino alla successiva sequenza </ (HTML4) o </script sequenza (HTML5) sono dati non elaborati, quindi if (x<y) può essere scritto senza alcuna codifica; ciò farebbe scombussolare i parser XML.

Nelle regole di analisi XML non ci sono elementi speciali e quindi la stessa istruzione dovrebbe essere scritta come if (x&lt;y) ; questo rovinerebbe i parser HTML.

Per consentire a < di essere scritto senza caratteri di escape e indicare la stessa cosa sia per i parser XML che HTML, puoi avvolgere lo script in una sezione CDATA XML, quindi proteggere i parser HTML da quel strano costrutto nascondendolo in un Commento JavaScript.

Se stai usando questo costrutto per permetterti di includere questi caratteri in una stringa letterale senza fuggire, non è abbastanza, perché devi comunque scappare sia la sequenza </ (per HTML) che ]]> (per XML). Un modo per sfuggire a quelle sequenze in una stringa JS letterale è sempre codificare <>& caratteri in \x3C , \x3E e \x26 rispettivamente ... nel qual caso non sarà più necessaria la Sezione CDATA.

I run the objects through a standard JSON stringifier which follows all the rules, then I replace </script with <\/script, not case sensitive. Is this sufficient?

Non necessariamente.

  1. Sintassi HTML. <\/script va bene per HTML ma non XHTML, come sopra.

  2. Sintassi JavaScript. Ci sono, a causa di una sfortunata svista nella progettazione di JSON, alcuni caratteri di controllo Unicode validi in JSON ma non validi in JavaScript.

In particolare i caratteri U + 2028 e U + 2029, Separatore di linee e paragrafi, che fungono da newline. L'iniezione di una nuova riga nel mezzo di una stringa letterale causerà molto probabilmente un errore di sintassi (letterale stringa non terminato).

Ci sono più caratteri di controllo che dovrebbero essere non validi nei valori letterali delle stringhe JS, ma che in pratica non interrompono i browser.

Se il codificatore JSON codifica abitualmente tutti i caratteri non ASCII, ciò non costituirà un problema.

Alternativa per ottenere la codifica JS incorporata a destra: evitare completamente gli script inline, inserire i dati nella pagina HTML (dove si applicano le normali regole di escape HTML) e recuperarli da script collegati usando i metodi DOM.

    
risposta data 26.01.2012 - 23:29
fonte
3

Risposta breve, sostituendo i caratteri < e > a livello globale con \u003c e \u003e consentirà l'incorporamento in HTML% degli elementi di<script> in modo sicuro e può essere eseguito su JSON valido senza interruzioni.

Per incorporarlo in XML, devi assicurarti che il JSON contenga solo caratteri che possono essere visualizzati in XML. Nello specifico, XML può contenere solo caratteri non di controllo , quindi devi anche \u.... sfuggire a tali caratteri.

Il link prende input JSON e produce un output che è JSON valido e che è sicuro da incorporare in HTML <script> elementi e all'interno XML <![CDATA[...]]> sezioni.

Given JSON-like content, converts it to valid JSON.

This can be attached at either end of a data-pipeline to help satisfy Postel's principle:

be conservative in what you do, be liberal in what you accept from others

     

Applicato a contenuti di tipo JSON di altri, produrrà JSON ben formato che dovrebbe soddisfare qualsiasi parser che usi.

     

Applicato al tuo output prima di inviarlo, causerà minori errori nella codifica e renderà più semplice incorporare il tuo JSON in HTML e XML.

     

uscita

     

L'output è JSON ben formato come definito da RFC 4627. L'output soddisfa tre proprietà aggiuntive:

     
  1. L'output non conterrà la sottostringa (senza distinzione tra maiuscole e minuscole) "</script" , quindi può essere incorporato all'interno di un elemento di script HTML senza ulteriore codifica.
  2.   
  3. L'output non conterrà la sottostringa "]]>" , quindi può essere incorporato in una sezione CDATA XML senza ulteriore codifica.
  4.   
  5. L'output è un'espressione JavaScript valida, quindi può essere analizzata da% di conversione di% di% co_de di Javascript (dopo essere stata racchiusa tra parentesi) o da eval . In particolare, l'output non conterrà letterali stringa con newline JS incorporate (U + 2028 Separatore di paragrafo o U + 2029 Separatore di riga).
  6.   

Sicurezza

     

Poiché l'output è JSON ben formato, passarlo a eval non avrà effetti collaterali e nessuna variabile libera, quindi non è né un vettore di iniezione di codice, né un vettore per l'estrazione di segreti.

     

Questa libreria garantisce solo che la stringa JSON → fase dell'oggetto Javascript non abbia effetti collaterali e non risolva variabili libere, e non può controllare in che modo il codice lato client successivo interpreta in seguito l'oggetto Javascript risultante. Quindi se il codice lato client prende parte dei dati analizzati controllati da un utente malintenzionato e lo restituisce tramite un potente interprete come JSON.parse o eval , allora il codice lato client potrebbe subire effetti collaterali indesiderati.

    
risposta data 17.10.2012 - 16:46
fonte

Leggi altre domande sui tag