trust(html)
Beschreibung
Wandelt einen HTML- oder SVG-String in unmaskiertes HTML oder SVG um. Verwenden Sie m.trust
nicht für ungeprüfte Benutzereingaben.
Versuchen Sie immer zuerst eine alternative Methode, bevor Sie die Verwendung von m.trust
in Betracht ziehen.
Signatur
vnode = m.trust(html)
Argument | Typ | Erforderlich | Beschreibung |
---|---|---|---|
html | String | Ja | Ein String, der HTML- oder SVG-Text enthält. |
returns | Vnode | Ein vertrauenswürdiger HTML-Vnode, der den Eingabe-String repräsentiert. |
Funktionsweise
Standardmäßig maskiert Mithril.js alle Werte, um eine Klasse von Sicherheitsproblemen zu verhindern, die als Cross-Site Scripting (XSS) bezeichnet werden.
var userContent = "<script>alert('evil')</script>";
var view = m('div', userContent);
m.render(document.body, view);
// equivalent HTML
// <div><script>alert('evil')</script></div>
Manchmal ist es jedoch erwünscht, Rich-Text und Formatierungs-Markup darzustellen. Um diesen Bedarf zu decken, erstellt m.trust
vertrauenswürdige HTML-Vnodes, die als HTML gerendert werden.
var view = m('div', [m.trust("<h1>Here's some <em>HTML</em></h1>")]);
m.render(document.body, view);
// equivalent HTML
// <div><h1>Here's some <em>HTML</em></h1></div>
Vertrauenswürdige HTML-Vnodes sind Objekte und keine Zeichenketten; daher können sie nicht mit normalen Zeichenketten verkettet werden.
Sicherheitsüberlegungen
Sie müssen die Eingabe für m.trust
bereinigen, um sicherzustellen, dass sich kein benutzergenerierter, bösartiger Code im HTML-String befindet. Wenn Sie einen HTML-String nicht bereinigen und ihn als vertrauenswürdigen String kennzeichnen, werden alle asynchronen JavaScript-Aufrufpunkte innerhalb des HTML-Strings ausgelöst und mit der Autorisierungsstufe des Benutzers ausgeführt, der die Seite anzeigt.
Sicherheitsangriffe werden häufig durch das Hinzufügen von onload
- oder onerror
-Attributen in <img>
- oder <iframe>
-Tags eingeschleust. Eine weitere Methode ist die Verwendung unausgeglichener Anführungszeichen, wie z. B. " onerror="alert(1)
, um ausführbaren Code in ungeprüfte Strings einzufügen.
var data = {};
// Beispiel für eine anfällige HTML-Zeichenkette
var description =
"<img alt='" + data.title + "'> <span>" + data.description + '</span>';
// Ein Angriff mit JavaScript-bezogenen Attributen
data.description = "<img onload='alert(1)'>";
// Ein Angriff mit unausgeglichenen Tags
data.description = "</span><img onload='alert(1)'><span";
// Ein Angriff mit unausgeglichenen Anführungszeichen
data.title = "' onerror='alert(1)";
// Ein Angriff mit einem anderen Attribut
data.title = "' onmouseover='alert(1)";
// Ein Angriff, der kein JavaScript verwendet
data.description =
"<a href='https://evil.com/login-page-that-steals-passwords.html'>Click here to read more</a>";
Es gibt unzählige, oft nicht offensichtliche Möglichkeiten, bösartigen Code zu erstellen. Es wird daher dringend empfohlen, eine Whitelist von zulässigen HTML-Tags, Attributen und Attributwerten zu verwenden, anstatt einer Blacklist, um die Benutzereingaben zu validieren/filtern. Es wird auch dringend empfohlen, einen geeigneten HTML-Parser anstelle von regulären Ausdrücken zur Bereinigung zu verwenden, da reguläre Ausdrücke extrem schwierig auf alle Sonderfälle zu testen sind.
Skripte, die nicht ausgeführt werden
Auch wenn es viele obskure Möglichkeiten gibt, einen HTML-String zum Ausführen von JavaScript zu bringen, sind <script>
-Tags eine Sache, die nicht ausgeführt wird, wenn sie in einem HTML-String vorkommt.
Aus historischen Gründen ignorieren Browser <script>
-Tags, die über innerHTML
in das DOM eingefügt werden. Sie tun dies, weil die Rendering-Engines nicht zum Parsing-Stadium zurückkehren können, sobald das Element bereit ist (und somit eine zugängliche innerHTML
-Eigenschaft hat), wenn das Skript so etwas wie document.write("</body>")
aufruft.
Dieses Browserverhalten kann für Entwickler, die von jQuery kommen, überraschend sein, da jQuery speziell Code implementiert, um Skript-Tags zu finden und sie in diesem Szenario auszuführen. Mithril.js folgt dem Browserverhalten. Wenn das jQuery-Verhalten gewünscht ist, sollten Sie entweder den Code aus dem HTML-String in eine oncreate
-Lebenszyklus-Methode verschieben oder jQuery verwenden (oder dessen Skript-Parsing-Code neu implementieren).
Vermeiden Sie das Vertrauen in HTML
Als allgemeine Regel sollten Sie m.trust
vermeiden, es sei denn, Sie rendern explizit Rich-Text und es gibt keine andere Möglichkeit, die gewünschten Ergebnisse zu erzielen.
// VERMEIDEN
m('div', m.trust('hello world'));
// BEVORZUGEN
m('div', 'hello world');
Vermeiden Sie blindes Kopieren und Einfügen
Eine häufige Missbrauchsart von m.trust
ist die Arbeit mit Drittanbieterdiensten, deren Tutorials HTML-Code zum Kopieren und Einfügen enthalten. In den meisten Fällen sollte HTML mit Vnodes geschrieben werden (typischerweise über das m()
-Hilfsprogramm).
Hier ist das Beispiel-Snippet für den Facebook Like Button:
<!-- Facebook SDK für JavaScript laden -->
<div id="fb-root"></div>
<script>
(function (d, s, id) {
var js,
fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.src = '//connect.facebook.net/en_US/sdk.js#xfbml=1';
fjs.parentNode.insertBefore(js, fjs);
})(document, 'script', 'facebook-jssdk');
</script>
<!-- Ihr "Gefällt mir"-Button-Code -->
<div
class="fb-like"
data-href="https://www.your-domain.com/your-page.html"
data-layout="standard"
data-action="like"
data-show-faces="true"
></div>
Und hier ist, wie man es in eine Mithril.js-Komponente umgestaltet, um m.trust
zu vermeiden:
var FacebookLikeButton = {
oncreate: function () {
(function (d, s, id) {
var js,
fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.src = '//connect.facebook.net/en_US/sdk.js#xfbml=1';
fjs.parentNode.insertBefore(js, fjs);
})(document, 'script', 'facebook-jssdk');
},
view: function () {
return [
m('#fb-root'),
m(
'.fb-like[data-href=https://www.your-domain.com/your-page.html][data-layout=standard][data-action=like][data-show-faces=true]'
),
];
},
};
Die obenstehende Mithril.js-Komponente kopiert den Skript-Tag-Code in den oncreate
-Hook und deklariert die verbleibenden HTML-Tags mit der m()
-Syntax von Mithril.js.
Vermeiden Sie HTML-Entities
Eine häufige Missbrauchsart von m.trust
ist die Verwendung für HTML-Entities. Ein besserer Ansatz ist die Verwendung der entsprechenden Unicode-Zeichen:
// VERMEIDEN
m('h1', 'Coca-Cola', m.trust('™'));
// BEVORZUGEN
m('h1', 'Coca-Cola™');
Unicode-Zeichen für Akzentzeichen können über ein Tastaturlayout für eine entsprechende Sprache eingegeben werden, und man kann auch Tastenkombinationen einprägen, um häufig verwendete Symbole zu erzeugen (z. B. Alt+0153
in Windows oder Option+2
auf dem Mac für das ™-Symbol). Eine andere einfache Methode ist das Kopieren und Einfügen des gewünschten Zeichens aus einer Unicode-Zeichentabelle. Eine weitere verwandte Methode ist die Eingabe eines escapeten Unicode-Codepunkts (z. B. "\u2122"
für das ™-Symbol).
Alle Zeichen, die als HTML-Entities darstellbar sind, haben Unicode-Gegenstücke, einschließlich nicht sichtbarer Zeichen wie
und ­
.
Um Kodierungsprobleme zu vermeiden, sollten Sie die Dateikodierung in der JavaScript-Datei auf UTF-8 setzen und das <meta charset="utf-8">
-Meta-Tag in der übergeordneten HTML-Datei hinzufügen.