trust(html)
- Core
- Optional
- Tooling
Description
Turns an HTML string into unescaped HTML. Do not use m.trust
on unsanitized user input.
Always try to use an alternative method first, before considering using m.trust
.
Signature
vnode = m.trust(html)
Argument | Type | Required | Description |
---|---|---|---|
html |
String |
Yes | A string containing HTML text |
returns | Vnode |
A trusted HTML vnode that represents the input string |
How it works
By default, Mithril escapes all values in order to prevent a class of security problems called XSS injections.
var userContent = "<script>alert('evil')</script>"
var view = m("div", userContent)
m.render(document.body, view)
// equivalent HTML
// <div><script>alert('evil')</script></div>
However, sometimes it is desirable to render rich text and formatting markup. To fill that need, m.trust
creates trusted HTML vnodes which are rendered as 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>
Trusted HTML vnodes are objects, not strings; therefore they cannot be concatenated with regular strings.
Security considerations
You must sanitize the input of m.trust
to ensure there's no user-generated malicious code in the HTML string. If you don't sanitize an HTML string and mark it as a trusted string, any asynchronous javascript call points within the HTML string will be triggered and run with the authorization level of the user viewing the page.
There are many ways in which an HTML string may contain executable code. The most common ways to inject security attacks are to add an onload
or onerror
attributes in <img>
or <iframe>
tags, and to use unbalanced quotes such as " onerror="alert(1)
to inject executable contexts in unsanitized string interpolations.
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='http://evil.com/login-page-that-steals-passwords.html'>Click here to read more</a>"
There are countless non-obvious ways of creating malicious code, so it is highly recommended that you use a whitelist of permitted HTML tags, attributes and attribute values, as opposed to a blacklist to sanitize the user input. It's also highly recommended that you use a proper HTML parser, instead of regular expressions for sanitization, because regular expressions are extremely difficult to test for all edge cases.
Scripts that do not run
Even though there are many obscure ways to make an HTML string run Javascript, <script>
tags are one thing that does not run when it appears in an HTML string.
For historical reasons, browsers ignore <script>
tags that are inserted into the DOM via innerHTML. They do this because once the element is ready (and thus, has an accessible innerHTML property), the rendering engines cannot backtrack to the parsing-stage if the script calls something like document.write("