2015-09-21 17 views
6

Używam deserializera JSON Newtonsoft. Jak można wyczyścić JSON dla XSS (cross site scripting)? Czyszczenie łańcucha JSON przed serializowaniem lub pisaniem jakiegoś niestandardowego konwertera/odkażania? Jeśli tak, nie jestem w 100% pewien, jak najlepiej to podejść.czyszczenie JSON dla XSS przed deserializacją

Poniżej znajduje się przykład JSON, który ma niebezpieczny skrypt wstrzyknięty i wymaga "czyszczenia". Chcę chcieć to zarządzać, zanim odserializuję to. Ale musimy wziąć pod uwagę wszystkie rodzaje scenariuszy XSS, w tym kodowany skrypt BASE64 itp., Dlatego problem jest bardziej złożony niż zastąpienie prostego ciągu REGEX.

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

Oto migawki z moich Deserializatora (JSON -> Object):

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 jest wysyłany z 3 interfejs partia UI, więc jest to dość widoczna, stąd walidacji po stronie serwera. Stamtąd staje się serializowany do wszystkich rodzajów obiektów i jest zwykle przechowywany w DB, później do pobrania i wyprowadzenia bezpośrednio w interfejsie opartym na HTML, więc wtrysk skryptu musi zostać złagodzony.

+1

Zaktualizowałem moje pytanie, aby rozwiązać problem "oczyścić". – MarzSocks

+0

To zależy od kontekstu. Czy możesz podać trochę szczegółów dotyczących sposobu wyświetlania danych? Czy będzie zawierał dane URL? Czy zostanie umieszczony bezpośrednio w kodzie HTML? Czy będzie dostępny tylko z javascript? czy to jest atrybut HTML? Zapobieganie XSS naprawdę zależy od kontekstu. – Gray

+1

JSON jest publikowany z interfejsu użytkownika innej firmy, więc jest dość wyeksponowany, a zatem po walidacji po stronie serwera. Stamtąd jest serializowany do wszystkich rodzajów obiektów i zwykle przechowywany w DB, później do pobrania i wyprowadzenia bezpośrednio w interfejsie opartym na HTML, więc tagi skryptów muszą być kontrolowane. Idealnie chcesz go wyczyścić, zanim jeszcze wejdzie w warstwę logiczną aplikacji, a serializator jest jedynym miejscem, w którym można je wszystkie rządzić. :-) – MarzSocks

Odpowiedz

3

Ok, mam zamiar spróbować zachować to dość krótki, bo to jest dużo pracy, aby napisać całą sprawę. Ale zasadniczo musisz skupić się na kontekście danych, których potrzebujesz do dezynfekcji. Z komentarzy do oryginalnego postu wynika, że ​​niektóre wartości w JSON będą używane jako HTML, które będą renderowane, a ten kod HTML pochodzi z niezaufanego źródła.

Pierwszym krokiem jest wyodrębnienie dowolnych wartości JSON, które mają być oczyszczone jako HTML, a dla każdego z tych obiektów należy uruchomić je za pomocą analizatora HTML i usunąć wszystko, czego nie ma na białej liście. Nie zapominaj, że będziesz potrzebować białej listy atrybutów.

HTML Agility Pack to dobre miejsce do rozpoczęcia parsowania HTML w C#. Jak zrobić tę część jest moim zdaniem osobnym pytaniem - i prawdopodobnie duplikatem połączonego pytania.

Twoje obawy dotyczące łańcuchów base64 wydają się nieco przesadzone w mojej opinii. To nie tak, że możesz po prostu umieścić aW5zZXJ0IGg0eCBoZXJl w dokumencie HTML, a przeglądarka go wyrenderuje. To może być nadużywane przez javascript (które zapobiegnie twojemu białemu listowi) i, do pewnego stopnia, poprzez adresy URL data: (ale to nie jest TAK złe, ponieważ javascript będzie działał w kontekście strony danych .Nie dobrze, ale nie jesteś " t automatycznie gobbuje pliki cookie). Jeśli musisz zezwolić na znaczniki a, część procesu musi sprawdzać, czy adres URL to http (s) (lub jakiekolwiek schematy, na które chcesz zezwolić).

Najlepiej byłoby uniknąć tej niewygodnej sytuacji, a zamiast tego użyć czegoś takiego jak markdown - wtedy można po prostu uciec z ciągu HTML, ale nie zawsze jest to coś, co możemy kontrolować. Nadal jednak musisz przeprowadzić weryfikację adresów URL.

+1

Skończyło się na tej trasie. Użył pakietu Agility HTML i odszyfrowanych wartości ciągu podczas konwersji do JSON. – MarzSocks

+1

Nie jesteś pewien, czy mówisz, że oczyszczasz je ZANIM je przechowujesz, ale jeśli tak, możesz chcieć przynajmniej przechowywać oryginał, na wypadek gdyby wystąpił błąd i uszkodziłeś niektóre dane. Jeśli jest to strona trzecia i nie przechowujesz jej w ogóle, to dobrze w każdym razie. Cieszę się, że było użyteczne. – Gray

2

Ciekawe !! Dzięki, że pytasz. zwykle używamy html.urlencode w kategoriach formularzy internetowych. Mam działającą aplikację korporacyjną api, która ma takie walidacje. Stworzyliśmy niestandardowe wyrażenie regularne do sprawdzenia poprawności. Proszę spojrzeć na to MSDN link.

Jest to model próbka stworzony do analizowania wniosku o nazwie KeyValue (powiedzmy)

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

Krok 1: Próbując z niestandardowym regex

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. 

Krok 2: Korzystanie HttpUtility .UrlEncode - this newtonsoft website link sugeruje poniższe wdrożenie.

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(); 
Powiązane problemy