Trust(html)
Popis
Převede řetězec HTML nebo SVG na neupravený HTML nebo SVG obsah. Nepoužívejte m.trust
na neošetřený uživatelský vstup.
Než použijete m.trust
, vždy se nejprve pokuste použít alternativní metodu.
Signatura
vnode = m.trust(html)
Argument | Typ | Povinný | Popis |
---|---|---|---|
html | String | Ano | Řetězec obsahující HTML nebo SVG text |
returns | Vnode | Důvěryhodný HTML vnode reprezentující vstupní řetězec |
Jak to funguje
Ve výchozím nastavení Mithril.js escapuje všechny hodnoty, aby se zabránilo bezpečnostním problémům zvaným XSS injekce.
var userContent = "<script>alert('evil')</script>";
var view = m('div', userContent);
m.render(document.body, view);
// equivalent HTML
// <div><script>alert('evil')</script></div>
Někdy je však žádoucí vykreslovat formátovaný text a značky pro formátování. Pro tento účel m.trust
vytváří důvěryhodné HTML vnodes, které jsou vykreslovány jako HTML.
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>
Důvěryhodné HTML vnodes jsou objekty, nikoli řetězce; proto je nelze zřetězit s běžnými řetězci.
Bezpečnostní aspekty
Musíte sanitizovat vstup pro m.trust
, abyste zajistili, že v HTML řetězci není žádný uživatelsky generovaný škodlivý kód. Pokud HTML řetězec neošetříte a označíte jej jako důvěryhodný, jakékoliv asynchronní volání JavaScriptu v něm obsažené se spustí s autorizací uživatele, který si stránku prohlíží.
Bezpečnostní útoky lze nejčastěji vložit přidáním atributů onload
nebo onerror
do tagů <img>
nebo <iframe>
. Další možností je použití nevyvážených uvozovek, například " onerror="alert(1)
, k vložení spustitelných kontextů do neošetřených interpolací řetězců.
var data = {};
// Sample vulnerable HTML string
var description =
"<img alt='" + data.title + "'> <span>" + data.description + '</span>';
// An attack using JavaScript-related attributes
data.description = "<img onload='alert(1)'>";
// An attack using unbalanced tags
data.description = "</span><img onload='alert(1)'><span";
// An attack using unbalanced quotes
data.title = "' onerror='alert(1)";
// An attack using a different attribute
data.title = "' onmouseover='alert(1)";
// An attack that does not use JavaScript
data.description =
"<a href='https://evil.com/login-page-that-steals-passwords.html'>Click here to read more</a>";
Existuje nespočet způsobů, jak vytvořit škodlivý kód, proto se důrazně doporučuje použít whitelist povolených HTML tagů, atributů a hodnot atributů, na rozdíl od blacklist pro sanitizaci uživatelského vstupu. Důrazně se také doporučuje použít správný HTML parser, namísto regulárních výrazů pro ošetření, protože regulární výrazy je extrémně obtížné otestovat pro všechny okrajové případy.
Skripty, které se nespouštějí
I když existuje mnoho způsobů, jak přimět HTML řetězec ke spuštění JavaScriptu, tagy <script>
jsou jednou z věcí, která se nespustí, když se objeví v HTML řetězci.
Z historických důvodů prohlížeče ignorují tagy <script>
, které jsou vloženy do DOM pomocí innerHTML
. Dělají to proto, že jakmile je element připraven a má tedy přístupnou vlastnost innerHTML
, vykreslovací enginy se nemohou vrátit zpět do fáze parsování, pokud skript volá něco jako document.write("</body>")
.
Toto chování prohlížeče se může zdát překvapivé pro vývojáře přicházející z jQuery, protože jQuery implementuje kód speciálně pro vyhledání script tagů a jejich spuštění v tomto scénáři. Mithril.js se řídí chováním prohlížeče. Pokud je požadováno chování jQuery, měli byste zvážit buď přesunutí kódu z HTML řetězce do metody životního cyklu oncreate
, nebo použití jQuery (nebo reimplementaci jeho kódu pro parsování skriptů).
Vyhněte se důvěřování HTML
Obecně platí, že byste se měli vyhnout používání m.trust
, pokud nevykreslujete explicitně formátovaný text a neexistuje žádný jiný způsob, jak dosáhnout požadovaných výsledků.
// AVOID
m('div', m.trust('hello world'));
// PREFER
m('div', 'hello world');
Vyhněte se slepému kopírování a vkládání
Jedním z běžných způsobů, jak zneužít m.trust
, je práce se službami třetích stran, jejichž tutoriály obsahují HTML kód, který má být zkopírován a vložen. Ve většině případů by měl být HTML kód psán pomocí vnodes (typicky pomocí utility m()
).
Zde je ukázkový fragment pro tlačítko To se mi líbí na Facebooku:
<!-- Load Facebook SDK for JavaScript -->
<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>
<!-- Your like 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>
A zde je návod, jak refaktorovat kód do komponenty Mithril.js způsobem, který se vyhýbá m.trust
:
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]'
),
];
},
};
Komponenta Mithril.js výše jednoduše zkopíruje kód script tagu do hooku oncreate
a deklaruje zbývající HTML tagy pomocí syntaxe m()
Mithril.js.
Vyhněte se HTML entitám
Běžným způsobem, jak špatně použít m.trust
, je použít jej pro HTML entity. Lepší přístup je použít odpovídající unicode znaky:
// AVOID
m('h1', 'Coca-Cola', m.trust('™'));
// PREFER
m('h1', 'Coca-Cola™');
Unicode znaky pro znaky s diakritikou lze zadávat pomocí rozložení klávesnice pro příslušný jazyk a lze si také zapamatovat klávesové zkratky pro vytváření běžně používaných symbolů (např. Alt+0153
ve Windows nebo Option+2
na Mac pro symbol ™). Další možností je jednoduše zkopírovat a vložit požadovaný znak z unicode tabulky znaků. Další možností je zadat escapovaný unicode codepoint (např. "\u2122"
pro symbol ™).
Všechny znaky, které jsou reprezentovatelné jako HTML entity, mají unicode protějšky, včetně neviditelných znaků, jako jsou
a ­
.
Abyste se vyhnuli problémům s kódováním, měli byste nastavit kódování souboru na UTF-8 v souboru JavaScript, a také přidat meta tag <meta charset="utf-8">
do hostitelského HTML souboru.