Laden...

[gelöst] asp.net MVC Inline code wird als XSS-Attacke erkannt

Erstellt von Craze89 vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.742 Views
C
Craze89 Themenstarter:in
52 Beiträge seit 2008
vor 12 Jahren
[gelöst] asp.net MVC Inline code wird als XSS-Attacke erkannt

Hallo Community,

ich habe da ein Problem mit einem inline Script in einer asp.net (MVC) Application.
Hintergrund für dieses inline Script ist, das eine dynamisch erstellte Tabelle des Views später auch in einer e-Mail verschickt werden soll.

Ich mache also folgendes:

Ich lege ein HiddenField für ein Property aus dem Viewmodel an


<%= Html.HiddenFor(x => x.exampleTable) %>

Beim document.ready lese ich das InnerHTML der Tabelle aus und schreibe dieses HTML in das Model


<script type="text/javascript">
    $(document).ready(function () {
        var innerHtml = document.getElementById("exampleTableId").innerHTML;
        $('#exampleTable').val(innerHtml);
    });
</script>

Wie bereits erwähnt, wird dieses Script als potentiell gefährlicher Code (mögliches Cross Site Scripting) erkannt. Habt ihr eine Idee, wie ich das ganze auch auf einem sicheren Weg machen kann, oder wie ich MVC mitteile, das dieses Script so gewünscht ist?

MfG
Craze

16.807 Beiträge seit 2008
vor 12 Jahren

Hallo,

generell ist das ein Feature, das MVC gegenüber andren Frameworks deutlich sicherer macht.
Das Problem dieser Stelle ist das Verwenden von HTML Chars.

Du hast an dieser Stelle in meinen Augen drei Möglichkeiten.

Variante A ( bedingt zu empfehlen ):
Du stellt die Validierung für diese Action und dieses Attribut einmalig außer Kraft.
Hierzu fügst Du das Attribut [ValidateInput(true, Exclude = "exampleTable")] der Action hinzu.

++Variante B ++( eher nicht zu empfehlen, da global Aktiv ):
Du gibst der Property exampleTable das Attribut [AllowHtml]

Variante C:
Du wandelst die innerHtml in einen sicheren String um ( Escaping ) und sendest diesen an den Server.

Bedenke unbedingt, dass Du bei A und B eine manuelle Validierung durchführen MUSST!!! und, dass alle Varianten bei unsachgemäßer behandlung Cross-Site-Scripting und andere "böse Dinge" zulassen!

Gruß

C
Craze89 Themenstarter:in
52 Beiträge seit 2008
vor 12 Jahren

Die Variante C hört sich doch sehr gut an (hätte ich auch selbst drauf kommen können 😄).

Und selbst die Varianten A und B sind besser, als alles was ich so über google gefunden haben. Da hieß es immer nur "stell die Validation in der Config aus" (so nach dem motto), was ja noch viel schlimmer ist.

Ich werds also erstmal mit deiner Variante C probieren und wenn mir das dann doch noch zu unsicher ist, werde ich das HTML für die Tabelle einfach serverseitig erzeugen und an den View zum Rendern übergeben.
Das wäre vermutlich die sicherste Variante oder?

Besten Dank für die Tipps!

MfG
Craze

16.807 Beiträge seit 2008
vor 12 Jahren

Ich speicher generell kein HTML ab, da sich das bei einer Oberflächenanpassung nicht umsetzen lässt, sondern nur die inhaltlichen Werte - das ist die sicherste Variante 😉

C
Craze89 Themenstarter:in
52 Beiträge seit 2008
vor 12 Jahren

Das mach ich im Normalfall auch nicht. Ich erstelle halt anhand von berechneten (teilweise flüchtigen) Daten eine Tabelle im View. Der Kunde hätte diese Tabelle aber gerne auch in der Mail, die er am Ende des Workflows kriegt.

Hab das Problem jetzt aber auch gelöst, habe im Netz ein recht nützliches Snippet gefunden mit dem man PartialViews als String "rendern" kann. Sprich ich render einmal den View + Partial mit den gegebenen Daten und einmal "render" ich den String des PartialViews, der dann in der Mail landet.

MfG
Craze

16.807 Beiträge seit 2008
vor 12 Jahren

Für doch Deine Lösung noch bitte hier an 😉

C
Craze89 Themenstarter:in
52 Beiträge seit 2008
vor 12 Jahren

Aber sichi das! 😄

Ich finde leider grad auf anhieb die Seite nicht mehr wo ichs gefunden habe, also gibts hier mal nur den code dazu.

Diese Methode erwartet also einen PartialView und das zugehörige ViewModel, aber anstatt diese zu rendern, wird der View einfach in den StringBuilder geschrieben.


public static string RenderPartialToString(string controlName, object viewData)
        {
            ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };

            viewPage.ViewData = new ViewDataDictionary(viewData);
            viewPage.Controls.Add(viewPage.LoadControl(controlName));

            StringBuilder sb = new StringBuilder();
            using (StringWriter sw = new StringWriter(sb))
            {
                using (HtmlTextWriter tw = new HtmlTextWriter(sw))
                {
                    viewPage.RenderControl(tw);
                }
            }

            return sb.ToString();
        }

Zu beachten ist, das man ggf. zusätzlich noch enthaltene CSS-classes durch styles ersetzen, oder die stylesheets anhängen muss. Außerdem sollte man die "\r"s und "\n"s entfernen.

Gruß
Craze