2015-09-21 30 views
6

Uso il deserializzatore JSON Newtonsoft. Come si può pulire JSON per XSS (cross site scripting)? O pulire la stringa JSON prima di deserializzare o scrivere una sorta di convertitore/disinfettante personalizzato? Se è così, non sono sicuro al 100% sul modo migliore per affrontarlo.pulizia JSON per XSS prima della deserializzazione

Di seguito è riportato un esempio di JSON a cui è stato iniettato uno script pericoloso e che necessita di "pulizia". Voglio una voglia di gestirlo prima di de-serializzarlo. Ma dobbiamo assumere tutti i tipi di scenari XSS, incluso lo script codificato BASE64, ecc., Quindi il problema è più complesso che una semplice stringa REGEX sostituisce.

{ "MyVar" : "hello<script>bad script code</script>world" } 

Ecco un'istantanea della mia deserializer (JSON -> Oggetto):

public T Deserialize<T>(string json) 
{ 
    T obj; 

    var JSON = cleanJSON(json); //OPTION 1 sanitize here 

    var customConverter = new JSONSanitizer();// OPTION 2 create a custom converter 

    obj = JsonConvert.DeserializeObject<T>(json, customConverter); 

    return obj; 
} 

JSON è pubblicato da una terza interfaccia di partito interfaccia utente, quindi è abbastanza esposto, da qui la convalida sul lato server. Da lì, viene serializzato in tutti i tipi di oggetti e di solito viene memorizzato in un DB, in seguito per essere recuperato e rilasciato direttamente nell'interfaccia utente basata su HTML, quindi l'iniezione di script deve essere mitigata.

+1

Ho aggiornato la mia domanda per indicare cosa intendo per "pulizia". – MarzSocks

+0

Dipende dal contesto. Potresti fornire alcuni dettagli su come verranno visualizzati i dati? Conterrà dati URL? Sarà inserito direttamente nell'HTML? Sarà accessibile solo da javascript? è un attributo HTML? La prevenzione dell'XSS dipende molto dal contesto. – Gray

+1

JSON viene pubblicato da un'interfaccia utente di terze parti, quindi è abbastanza esposto e quindi la convalida lato server. Da lì viene serializzato in tutti i tipi di oggetti e di solito viene memorizzato in un DB, in seguito per essere recuperato e emesso direttamente nell'interfaccia utente basata su HTML, quindi i tag di script devono essere controllati. Idealmente, vuoi pulirlo prima che entri anche nel livello logico dell'applicazione e il serializzatore è l'unico posto dove dominarli tutti. :-) – MarzSocks

risposta

3

Ok, sto andando a cercare di mantenere questo piuttosto breve, perché questo è un sacco di lavoro per redigere il tutto. Ma, in sostanza, è necessario concentrarsi sul contesto dei dati che è necessario disinfettare. Dai commenti sul post originale, sembra che alcuni valori nel JSON saranno utilizzati come HTML che verrà reso e questo HTML proviene da una fonte non attendibile.

Il primo passaggio consiste nell'estrarre qualsiasi valore JSON che deve essere disinfettato come HTML e, per ciascuno di questi oggetti, è necessario eseguirli tramite un parser HTML e rimuovere tutto ciò che non si trova in una whitelist. Non dimenticare che avrai anche bisogno di una whitelist per gli attributi.

HTML Agility Pack è un buon punto di partenza per l'analisi di HTML in C#. Come fare questa parte è una domanda a parte a mio parere - e probabilmente un duplicato della domanda collegata.

La mia preoccupazione per le stringhe base64 sembra un po 'troppo enfatizzata a mio parere. Non è che puoi semplicemente inserire aW5zZXJ0IGg0eCBoZXJl in un documento HTML e il browser lo renderà. Può essere abusato tramite javascript (che la tua lista bianca impedirà) e, in una certa misura, tramite gli URL data: (ma questo non è così male, dato che javascript verrà eseguito nel contesto della pagina dei dati. Non va bene, ma non lo sei " t automaticamente inghiottendo i cookie con questo). Se devi consentire i tag a, parte del processo deve essere la convalida che l'URL sia http (s) (o qualunque schema tu voglia consentire).

Idealmente, si eviterebbe questa situazione spiacevole, e invece si usa qualcosa come markdown - allora si potrebbe semplicemente sfuggire alla stringa HTML, ma questo non è sempre qualcosa che possiamo controllare. Dovresti comunque fare qualche convalida dell'URL.

+1

Ho finito per seguire questa strada. Utilizzato l'HTML Agility Pack e valori di stringa sterilizzati durante la conversione in JSON. – MarzSocks

+1

Non sai se stai dicendo che li disinfetti PRIMA di archiviarli, ma se lo sei, potresti almeno conservare l'originale nel caso ci fosse un bug e tu corrompessi alcuni dati. Se è di terze parti e non lo memorizzi affatto, allora va bene in entrambi i casi. Sono contento che sia stato utile. – Gray

2

Interessante !! Grazie per avermelo chiesto normalmente usiamo html.urlencode in termini di moduli web. Ho una web API aziendale in esecuzione con convalide come questa. Abbiamo creato una regex personalizzata per la convalida. Si prega di dare un'occhiata a questo MSDN link.

questo è il modello di esempio creato per analizzare la richiesta di nome KeyValue (diciamo)

public class KeyValue 
{ 
    public string Key { get; set; } 
} 

Fase 1: Cercando con una regex personalizzato

var json = @"[{ 'MyVar' : 'hello<script>bad script code</script>world' }]"; 

     JArray readArray = JArray.Parse(json); 
     IList<KeyValue> blogPost = readArray.Select(p => new KeyValue { Key = (string)p["MyVar"] }).ToList(); 

     if (!Regex.IsMatch(blogPost.ToString(), 
      @"^[\p{L}\p{Zs}\p{Lu}\p{Ll}\']{1,40}$")) 
      Console.WriteLine("InValid"); 
      //   ^means start looking at this position. 
      //   \p{ ..} matches any character in the named character class specified by {..}. 
      //   {L} performs a left-to-right match. 
      //   {Lu} performs a match of uppercase. 
      //   {Ll} performs a match of lowercase. 
      //   {Zs} matches separator and space. 
      //   'matches apostrophe. 
      //   {1,40} specifies the number of characters: no less than 1 and no more than 40. 
      //   $ means stop looking at this position. 

Fase 2: Utilizzando HttpUtility .UrlEncode - this newtonsoft website link suggerisce l'implementazione di seguito.

string json = @"[{ 'MyVar' : 'hello<script>bad script code</script>world' }]"; 

     JArray readArray = JArray.Parse(json); 
     IList<KeyValue> blogPost = readArray.Select(p => new KeyValue {Key =HttpUtility.UrlEncode((string)p["MyVar"])}).ToList();