Sichere Möglichkeit, dynamische Werte in externe JavaScript-Dateien einzufügen

8

Ich implementiere Richtlinien für Inhaltssicherheitsrichtlinien mit den folgenden Richtlinien

Content-Security-Policy: default-src 'self'

muss also Inline-Skript vermeiden, da es nicht ausgeführt wird.

In der MVC-Anwendung werden jedoch bestimmte Funktionen wie z. B. Editor-Vorlagen mit Inline-Skript verwendet. z.B. tinymce_jquery_full.cshtml enthält

%Vor%

Was ist eine gute Möglichkeit, dynamische Werte in externe .js -Dateien einzubinden, wenn ein CSP verwendet wird?

Mein gegenwärtiges Denken ist einer von zwei Wegen:

C # Generiertes JavaScript

Ähnlich wie JSONP funktioniert, außer dass ich in der URL keinen Rückruf angegeben habe - passiere ich einfach die dynamischen Werte. In jeder Datei, die dynamisches JavaScript benötigt, schließe ich einen Link wie

ein %Vor%

was auf ScriptController 's Foo action trifft, die den Inhalt vom Typ text/javascript zurückgibt und den dynamischen Wert bar einfügt. Dies erscheint mir als eine zuverlässige Methode, wenn auch ein wenig klobig und es einige der Vorteile der Verwendung eines CSP in erster Linie besiegt (fast so einfach versehentlich einfügen uncodierten Text und verursachen XSS wie es ohne CSP ist).

Versteckte Formularfelder

Dynamische Werte werden in die Seite eingefügt:

%Vor%

und diese Werte werden in den externen JavaScript-Dateien nachgeschlagen:

%Vor%

Dies wird funktionieren, aber es könnte unangenehm sein, wenn mehrere dynamische Steuerelemente auf der Seite vorhanden sind oder wenn es mehr als ein Steuerelement desselben Typs gibt. Das Problem besteht darin, wie jedes .js -Skript effizient mit seinen versteckten Feldern abgeglichen werden kann.

Gibt es dafür eine bessere Lösung oder gibt es fertige Frameworks, die ich nutzen kann?

    
SilverlightFox 29.01.2014, 10:28
quelle

1 Antwort

1
  

$ ('# @ ViewData.TemplateInfo.GetFullHtmlFieldName (string.Empty)')

Ja, das ist im Allgemeinen kein guter Ansatz. Razor wird standardmäßig HTML-Escape, aber der Kontext ist nicht einfach HTML hier, es ist:

  • ein Bezeichner innerhalb
  • ein CSS-Selektor, innerhalb
  • ein JavaScript-String-Literal, innerhalb
  • eine JavaScript-Anweisung, innerhalb
  • ein HTML-CDATA-Element ( <script> )

also nur HTML-Escaping ist das Falsche - alle Zeichen, die im Kontext von Selektoren oder JS-String-Literalen (wie Punkt, Backslash, Apostroph, Zeilentrennzeichen ...) sind, würden diese Aussage brechen.

>

Vielleicht ist das für dieses spezielle Beispiel nicht besonders wichtig, vorausgesetzt, das Ergebnis von GetFullHtmlFieldName wird immer etwas Sicheres sein, aber das ist keine gute Annahme für den allgemeinen Fall.

  

C # Generierte JavaScript: ein wenig klobig und es besiegt einige der Vorteile der Verwendung eines CSP

Einverstanden, vermeiden Sie das. Es ist in der Regel ein Problem, das Zwischenspeichern richtig zu machen und die Informationen aus dem ASP, der den Seiteninhalt erzeugt, auf die Seite zu übertragen, die das Skript generiert.

Auch das Generieren von JavaScript ist nicht unbedingt so einfach. ASP- und Razor-Vorlagen bieten keinen automatischen JS-Escaper. JSON Encoding macht es fast, abgesehen von den Niggling-Unterschieden zwischen JSON und JS (zB U + 2028 und U + 2029).

  

Versteckte Formularfelder

Ganz allgemein, indem Sie die Informationen in das DOM eingeben. Versteckte Formularfelder sind eine Möglichkeit, dies zu tun; data- -Attribute sind eine weitere häufig verwendete. In beiden Fällen bevorzuge ich den DOM-Ansatz.

Wenn Sie versteckte Formularfelder verwenden, sollten Sie das name -Attribut wahrscheinlich entfernen, als ob sie sich in einem echten <form> befinden, in dem Sie die Daten, die Sie in JS übergaben, normalerweise nicht wirklich übermitteln möchten.

Auf diese Weise können Sie den Inhalt mit normalem HTML-Standard-Escaping in die Vorlage einfügen. Wenn Sie mehr Struktur benötigen, können Sie die zu übergebenden Daten immer JSON-encodieren. jQuerys data() helper wird in diesem Fall automatisch auch JSON.parse für Sie übernehmen.

%Vor%

(Obwohl ... für den speziellen Fall der Auswahl von Elementen, auf die ein HTML-Editor angewendet werden soll, wäre es vielleicht einfacher, class="tinymce" zu verwenden und mit $('.tinymce').tinymce(...) anzuwenden?)

    
bobince 29.01.2014, 13:22
quelle