Wprowadzenie

W tym artykule postaram się wytłumaczyć czym jest XSS (Cross Site Scripting). Przedstawię kilka przykładów, które są podatne na XSS oraz próbują wstrzyknąć skrypty do naszej strony. W kolejnej części skupię się na prezentacji sposobów zabezpieczania się przed takimi atakami.

Cross Site Scripting jest problemem z którym zmaga się wiele stron internetowych. Zgodnie z WhiteHat Security 50% stron internetowych jest narażone na takie ataki. Jako programista stron internetowych, warto poznać, czym są ataki tego typu oraz jak możemy się przed nimi bronić.

XSS to nic innego jak wstrzykiwanie skryptów po stronie klienta do strony internetowej. Pojawia się pytanie, jak użytkownik może wstrzyknąć takie skrypty do naszej strony internetowej? Może to zostać zrobione m.in. przez wszystkie kontrolki przyjmujące parametry od użytkownika. Ataki tego typu mogą zostać przeprowadzone na poniższe sposoby:

  • TextBox (kontrolki wejściowe);
  • Argumenty zapytania w adresie URL (query strings);
  • Ciasteczka (cookies);
  • Zmienne sesji (session variables);
  • Zmienne aplikacji (application variables);
  • Pobieranie danych z zewnętrznych bądź współdzielonych zasobów.
Przejdziemy teraz do przygotowania najbardziej prymitywnego przykładu a następnie skupimy się sprawdzeniu jak możemy zabezpieczyć się przed takimi atakami przy użyciu ASP.NET MVC.


Użycie kodu

Na wstępie warto wiedzieć, że ASP.NET MVC dostarcza mechanizm, który pozwala przeciwdziałać atakom tego typu. Mechanizm ten jest aktywny automatycznie po utworzeniu nowego projektu. My jednak chcemy dowiedzieć się czym są ataki tego typu, dlatego też, obejdziemy ten mechanizm tak, aby być w stanie wygenerować taki atak.

Utworzony przez nas widok będzie wyświetlał identyfikator wprowadzony przez użytkownika:

XSS - wprowadzenie

Kontroler przedstawia się w następujący sposób:

public class XSSController : Controller
    {
		// GET: XSS
		public ActionResult Index()
        {
			// Używamy metody, która obchodzi zabezpieczenia walidacji
			// Tylko w ramach testów!
			var id = Server.UrlDecode(Request.Unvalidated("id"));
			// Kod, którego powinniśmy używać nominalnie
			// string id = Request.QueryString["id"] as string;
			string text = "";
			if(id == null)
			{
				text = "NA";
			}
			else
			{
				text = id;
			}
			ViewBag.CurrentId = text;
			return View();
        }
    }
Z perspektywy normalnego użytkownika wszystko działa poprawnie. Problem pojawia się, gdy ktoś przekaże tekst w postaci HTML’a lub skrypt napisany przy użyciu JavaScript. Spróbujmy jako parametr przekazać łańcuch znaków w postaci:
<h3>Witaj z XSS</h3>:

XSS - wysłanie złośliwej wiadomości

W tym momencie możecie zauważyć problem. Użytkownik przekazał HTML, który został dodany do naszej strony. To jest najprostszy możliwy przykład, wyobraźmy sobie sytuację w której użytkownik byłby zdolny do usunięcia zawartości oryginalnej strony i wyświetlenia czegoś zupełnie innego.

Ta sama sytuacja dotyczy JavaScript. Skrypt taki może zostać wstrzyknięty do naszej strony internetowej. Spróbujmy wstrzyknąć skrypt w postaci:
<script>alert('jesteś ofiarą ataku hakerskiego!’);</script> :

XSS - atak hakerski

Wykonywanie ataków XSS przy pomocy pól wejściowych
W tym przykładzie dodamy kontrolkę TextBox, która będzie przyjmowała imię użytkownika. Następnie, po wciśnięciu przycisku, zostanie wyświetlone powitanie:

XSS - powitanie

Podobnie jak we wcześniejszym przykładzie wszystko wydaje się w porządku do momentu, aż ktoś nie spróbuje dodać fragmentu HTML lub jakiegoś skryptu. Spróbujmy zatem dodać obrazek na stronie, który przesłoni całą zawartość. Zamiast wprowadzać swoje prawdziwe imię dodamy poniższy fragment kodu:
<img src='http://2.bp.blogspot.com/-dmg3602DpM0/UgX3w37b1ZI/AAAAAAAAAD4/Okqrm9nqpIQ/s400/404_error_page.jpg' style='position:absolute;top:51px;display:block' /image480Format; .
Po wciśnięciu przycisku ‘Powitania’ naszym oczom ukaże się poniższy widok:

XSS - zakażony obrazek

Mam nadzieje, że temat XSS jest już zrozumiały – przynajmniej jego podstawy. Możemy teraz przejść do tematu zabezpieczenia naszej strony internetowej przed atakami tego typu.


Zapobieganie Cross Site Scripting

ASP.NET MVC dostarcza mechanizm, który pozwala przeciwdziałać atakom tego typu. Mechanizm ten jest aktywny automatycznie po utworzeniu nowego projektu.

Walidacja żądania jest mechanizmem, który analizuje żądanie HTTP i sprawdza czy zawiera potencjalnie niebezpieczne zawartości. Mówimy tutaj o znacznikach HTML lub kodzie JavaScript w ciele, nagłówku, argumentach zapytania w adresie URL, ciasteczkach czy przesyłanym żądaniu. Mechanizm ten sprawdza wystąpienia znaczników ponieważ mogą zostać wykorzystane do przeprowadzenia szkodliwych ataków.

Zakomentujemy obejście walidacji, którego używaliśmy w poprzednich przykładach:

public ActionResult Index()
{
	// Używamy metody, która obchodzi zabezpieczenia walidacji
	// Tylko w ramach testów!
	// var id = Server.UrlDecode(Request.Unvalidated("id"));
	// Kod, którego powinniśmy używać nominalnie
	string id = Request.QueryString["id"] as string;
	string text = "";
	if(id == null)
	{
		text = "NA";
	}
	else
	{
		text = id;
	}
	ViewBag.CurrentId = text;
	return View();
}
A następnie spróbujemy wstrzyknąć przykładowy skrypt:

Detekcja ataku XSS w MVC

Ale oprócz wbudowane mechanizmu należy przestrzegać poniższych zasad, aby ustrzec się takich ataków:
  • ograniczyć możliwość wprowadzania znaków do tych akceptowalnych przez dane pole;
  • nigdy nie ufać danym wprowadzanym przez użytkownika.
  • jeżeli dane pochodzą z zewnętrznego źródła danych (dane niezaufane), należy dokonać ich sprawdzenia przed wyświetleniem użytkownikowi. Można tego dokonać w poniższy sposób:
    var encodedHtml = Server.HtmlEncode(untrustedData);
    

W ramach przestrzegania powyższych zasad wróćmy do przykładu związanego z powitaniem użytkownika na naszej stronie internetowej. Nasze pole tekstowe nie miało żadnych ograniczeń co do liter alfabetu, liczb czy dodatków znaków. Dodamy prostą walidację, która sprawdzi przesyłany ciąg znaków:

function Welcome() {
    var name = $("#name").val();
    var encodedName = name.replace(/[^a-z0-9]/gi, '');
    $("#container").append("Witaj " + encodedName);
}
Dzięki użyciu powyższej funkcji nie będą dozwolone żadne inne znaki niż litery i cyfry. Pozwoli to zabezpieczyć nasz widok przed wyświetlaniem niepożądanych treści:

Rozpoznanie ataku XSS w MVC


Podsumowanie

Mam nadzieję, że artykuł pomógł Wam w zrozumieniu mechanizmu Cross Site Scripting oraz sposobów zabezpieczania strony internetowej przed takimi rodzajami ataków - w stopniu podstawowywm. Równolegle z tymi mechanizmami zalecane jest używanie narzędzi od firm trzecich, które pozwalają na dodatkową ochronę. Jedną z takich bibliotek jest AntiXSS (http://wpl.codeplex.com/). Użycie takich bibliotek pozwoli na dodatkowe zabezpieczenia, jeżeli te dostarczone przez framework okażą się niewystarczające.