2012-11-20 10 views
8

Mi capita di leggere su XSS e su come evitarlo. Da quello che ho letto, sono venuto a sapere che abbiamo bisogno del filtraggio degli input, della corretta gestione del codice dell'applicazione e della codifica dell'output per rendere l'applicazione Web un po 'sicura per XSS. Dopo aver esaminato diversi articoli, persistono diversi dubbi.Alcuni chiarimenti riguardanti XSS

  • Quando ho provato jQuery.text ("untrusted_data") o element.text = untrusted_data, il browser sembra essere la codifica del contenuto perfettamente, ma ho letto da qualche altra parte che sul lato client la codifica non dovrebbe essere attendibile e devi "sempre" codificare sul lato server. Perché la codifica sul lato client non è considerata sicura?

  • Ogni volta che ho cercato di impostare il valore utilizzando jQuery.val (untrusted_data) o element.value = untrusted_data sembra essere abbastanza sicuro. Quindi è davvero XSS sicuro o mi sono perso ogni caso qui?

  • Inoltre, mi capita di leggere da qualche parte che jQuery.setAttribute (attrName, untrusted_data) e setAttribute (attrName, untrusted_data) sono generalmente considerati sicuri solo se i nomi attributo non includono gli attributi basati su URL Contesto (src, href ecc.) O Gestori di eventi (onClick, onMouseOver, ecc.). In questo caso, come dovrei impostare un attributo href usando setAttribute ("href", untrusted_data)? EncodeForHtmlAttribute (untrusted_data) dal lato server è il giusto approccio?
  • Come devo gestire la creazione dinamica di HTML. Si consideri l'esempio di seguito

<div id="divName1" onClick="copyData()">untrusted_data</div> <div id="divName2"></div>

function copyData() 
{ 
    var divValue = jQuery("#divName1").html(); 
    jQuery("#divName2").html(divValue);/XSS Here 
} 

Quello che voglio ottenere è quello di ottenere il testo da divName1 e incollarlo al contenuto del divName2. Il codice che ho scritto sopra è vulnerabile all'XSS. Posso cambiare questo

jQuery ("# divName2"). Testo (divValue)

Quindi, questo garantirà la codifica, ma, come ho capito, diciamo che la codifica sul lato client è a rischio e dovrebbe essere usata solo la codifica lato server. Come dovrei scrivere questo per essere sicuro XSS senza usare la codifica lato client? Sono un po 'confuso qui :(. Si prega di aiutarmi a chiarire questi dubbi.

+0

'element.text' stesso è sicuro, ma è possibile riscontrare problemi se si utilizza l'interpolazione delle stringhe per passare i dati al codice client. –

risposta

8

Questo è un sacco di domande in una volta.

Perché la codifica sul lato client considerato non sicuro?

La codifica lato client va bene finché viene eseguita correttamente e in modo coerente.La codifica client-side spesso ha una barra inferiore poiché non deve preoccuparsi degli attacchi a livello di codifica dei caratteri come gli attacchi UTF-7.

Ogni volta che ho provato a impostare il valore utilizzando jQuery.val (untrusted_data) o element.value = untrusted_data sembra essere abbastanza sicuro. Quindi è davvero XSS sicuro o mi sono perso ogni caso qui?

Supponendo che untrusted_data sia una stringa e che l'elemento il cui valore viene impostato sia un nodo di testo normale in un elemento di flusso o di blocco, allora stai bene. È possibile che si verifichino problemi se il nodo al quale viene assegnato il valore è un nodo di testo in un elemento <script> o un URL, un gestore eventi o un nodo di attributo stile o qualsiasi cosa correlata a <object>.

Inoltre, mi capita di leggere da qualche parte che jQuery.setAttribute (attrName, untrusted_data) e setAttribute (attrName, untrusted_data) sono generalmente considerati sicuri solo se i nomi degli attributi non comprende attributi basati URL Context (src, href ecc.) o Event Handlers (onClick, onMouseOver ecc.). In tal caso,

Ciò è parzialmente corretto. Altri attributi hanno bordi taglienti come style e molte cose relative a <object> e <embed> e <meta>.

Se non si conosce molto dell'attributo, non esporlo a dati non attendibili. Le cose generalmente sicure sono attributi che contengono contenuto testuale come title o che hanno valori numerati come dir=ltr e dir=rtl.

Una volta che si hanno a che fare con attributi che richiedono valori più complessi, si corre il rischio che gli aggressori sfruttino estensioni oscure del browser come -moz-binding negli attributi style.

sembra essere abbastanza sicuro

Landmines sembrano essere al sicuro fino a quando fate un passo su di loro.

Non si può concludere molto da qualcosa "apparentemente sicuro". Hai davvero bisogno di guardarlo e capire cosa può potenzialmente andare storto, e organizzare le cose in modo che tu sia a rischio solo quando c'è una tempesta perfetta di cose che vanno storte (P (disaster) = P (failure0) * P (failure1) * ...) e che non sei a rischio quando una sola cosa non funziona (P (disaster) = P (failure0) + P (failure1) * P (! failure0) + ...).

come dovrei impostare un attributo href utilizzando setAttribute ("href", untrusted_data)?

Non farlo senza whitelisting il protocollo.

if (!/^https?:\/\//i.test(untrusted_data) && !/^mailto:/i.test(untrusted_data)) { 
    throw new Error('unsafe'); 
} 

Is encodeForHtmlAttribute (untrusted_data) dal lato server il modo giusto di approccio?

No. La codifica HTML del valore passato a setAttribute è ridondante e non consente di preservare le proprietà di sicurezza. <iframe srcdoc> potrebbe essere un'eccezione rara dal momento che il suo contenuto è HTML se il mio ricordo delle recenti modifiche alle specifiche è corretto.

Quello che voglio ottenere qui è ottenere il testo da divName1 e incollarlo nel contenuto di divName2. Il codice che ho scritto sopra è vulnerabile all'XSS.

Non scherzare con HTML. I getter dei browser '.innerHTML sono buggy e a volte questo porta a exploit come con i backtick che agiscono come delimitatori di valore in IE. Basta clonare i nodi da uno all'altro. Qualcosa di simile al di sotto dovrebbe farlo:

var div1 = $('#divName1'); 
for (var child = div1[0].firstChild(); child; child = child.nextSibling) { 
    $('#divName2').append([child.cloneNode(true)]); 
} 

posso cambiare questo per

jQuery("#divName2").text(divValue) 

Questo va bene se quello che cercate è il contenuto testuale.

+1

Risposta decente. Solo per aggiungerne un po '- come ha detto l'autore, anche gli attributi dovrebbero essere sterilizzati. Puoi farlo in modo relativamente semplice lato server o lato client: la principale difficoltà è l'ampia gamma di attacchi che possono essere perpetrati su di essi. Ci sono alcuni ottimi esempi sul web degli script di filtraggio. –

+2

'Le mine terrestri sembrano essere sicure finché non le calpesti. Questo è il miglior riepilogo che abbia mai riscontrato per qualsiasi tipo di problema di sicurezza IT, in cui la soluzione proposta 'sembrava abbastanza sicura' ... – ppeterka

+0

@Mike Grazie mille per la risposta dettagliata :) –