03 April 2012 ASP.NET MVC, XSS Robert Muehsig

Was der Benutzer eingibt ist böse. Die Chance, dass ein “böser” Nutzer Javascript in die eigene Anwendung einschleusen möchte ist verdammt hoch. Diese Art der Angriffe nennt man “Cross-Site-Scripting”.

Kurzeinführung XSS

Ziel des Angreifers ist es, bösen Schad-Code in das System zu bringen, mit dem Ziel andere Nutzer auszuspähen oder Aktionen in ihrem Namen zu machen. Schafft es z.B. ein Angreifer ein Javascript Schnipsel in das System zu schleusen, könnten nun die privaten Cookie-Daten eines anderen Nutzers abgegriffen werden oder per Javascript werden ungewollte Aktionen ausgelöst.

Wunderbare Beispiele findet man auf dieser Seite: http://ha.ckers.org/xss.html. Unser Ziel ist es also, die Eingabe als auch die Ausgabe “sicher” zu machen.

Browser sind blöd

Input-Validierung ist nicht trivial. Wer denkt, dass man einfach nach öffnenden und schließenden Tags ausschau halten muss, wird überrascht sein wie kreativ Browser die falschen Tags dennoch interpretieren!

Beispiel eines bösen Schadcodes

"<SCRIPT/XSS SRC=\"htpp://ha.ckers.org/css.js\">

Trotz dessen, dass “SCRIPT/XSS” ohnehin kein richtiger Tag ist und “htpp” auch nicht korrekt ist, versucht der Browser trotzdem die böse Javascript Datei zu laden.

Selbst wenn das schließende Tag nicht vorhanden ist, wird das Javascript versucht zu laden. Hier gibt es noch ganz viele tolle Beispiele.

Eingaben-Validierung: Request Validation von ASP.NET – nicht anfassen!

ASP.NET ist in dieser Hinsicht recht “robust”, wenn nicht sogar sehr genau. Sobald ein öffnendes oder schließendes Tag gefunden wird, gibt es eine Security Exception:

“A potentially dangerous Request.QueryString value was detected from the client (searchTerm="<foobar").”

image

Die Request Validation kann man anpassen, allerdings reisst die Variante von Martin ungewollt löcher in die Applikation, weil die AntiXSS Library nicht genau hinschaut. Wenn der Angreifer anstatt “<script src=”…”> das schließende “>” weg lässt, erkennt die Library den Schadcode nicht. XSS, hello!

Empfehlung: Finger davon lassen. Nur wenn man ganz genau weiß, was man da macht, kann man sich daran wagen. Wer z.B. bei Passwörtern die Zeichen “>” und “<” zulassen möchte, der kommt mit dem AllowHtml Attribut weiter. Bei anderen Fällen muss man enorm aufpassen!

Ausgabe absichern

Ausgaben sollten Prinzipell Html-Encoded sein. Alles andere ist gefährlich!

Html.DisplayFor – KEIN HTML ENCODING!

Folgender Code von mir (der Code stammt aus einer Frage, welche ich bei Stackoverflow gestellt habe).

Szenario: Böser Schadcode ist im System und wird nun zum View geschickt.

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "<SCRIPT/XSS SRC=\"htpp://ha.ckers.org/css.js\">";

        User foo = new User();
        foo.Name = "<SCRIPT/XSS SRC=\"htpp://ha.ckers.org/css.js\">";

        return View(bla);
    }

    public ActionResult About()
    {
        return View();
    }
}

public class User
{
    public string Name { get; set; }
} 

 

Nun zur Ausgabe – das Ergebnis steht bereits da (und hat mich jedenfalls überrascht)

The View:

@Html.TextBoxFor(m => m.Name) <br/> ||| <-- will be encoded

@Html.Encode(ViewBag.Message)<br/> ||| <-- will be double encoded

@Model.Name <br/> ||| <-- will be encoded 

@Html.DisplayTextFor(m => m.Name) <-- no encoding
<br/> ||| 

 

Wer “DisplayTextFor” nutzt, sollte also wissen, was er tut und es vorher über Html.Encode absichern. Oder einfach nur den Razor @Syntax nehmen – der macht es immer.

MvcHtmlStrings? Machen die nicht ein encoding?

Mit MVC3 wurden auch die MvcHtmlStrings eingeführt, allerdings darf man nicht denken, dass diese per Default alles encoden:

var mvcHtmlString = MvcHtmlString.Create("<SCRIPT/XSS SRC=\"htpp://ha.ckers.org/css.js\">").ToHtmlString();

    var encoded = HttpUtility.HtmlEncode("<SCRIPT/XSS SRC=\"htpp://ha.ckers.org/css.js\">");

 

Wenn ich beides nun ausgebe wird der mvcHtmlString ohne HtmlEncoding dargestellt. ToHtmlString macht keine encoding!

Erst durch das HtmlEncode wird es sicher! Näheres gibt es in dieser Stackoverflow Frage.

Nutzereingaben sind gefährlich! Browser lassen viel durchgehen, daher doppelt wachsam sein!

XSS Attacken sind sehr verbreitet. ASP.NET ist nicht mehr oder weniger anfällig für XSS, man muss allerdings das Framework zu nutzen wissen.


Written by Robert Muehsig

Software Developer - from Dresden, Germany, now living & working in Switzerland. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de

If you like the content and want to support me you could buy me a beer or a coffee via Litecoin or Bitcoin - thanks for reading!