Exploring How lit-html Works: TemplateResult and SVGTemplateResult constructors (2)
Tags: javascript, typescript, webcomponents, devjournal
Published: 2020-01-06 14:58:37

In this series, How lit-html works, I will explore (not explain) internal implementation of [lit-html](https://lit-html.polymer-project.org/).

In [the previous post](https://dev.to/nozomuikuta/exploring-how-lit-html-works-templateresult-and-svgtemplateresult-constructors-g5h), we saw what `TemplateResult` and `SVGTemplateResult` look like, but  I skipped some points.

In this post, I will explore Trusted Types API.

---

By the way, before writing this post, I found [the official documentation that explains how lit-html works](https://github.com/Polymer/lit-html/wiki/How-it-Works), which would be helpful if you want to grasp overview quickly.

But, I will keep reading code to expand my knowledge. This is why I put [#devjournal](https://dev.to/t/devjournal) tag on the posts of this series.

---

# Trusted Types API

Trusted Types is an experimental API that makes it secure that DOM API, which by default can be sink of cross-site scripting (XSS).

It is obviously dangerous to allow users to assign a string to `innerHTML` property because they can let any valid HTML, even `script` element, be executed. Developers would say they don't do such a thing, but the more complicated the code gets, it becomes the more difficult to find the sinks.

Here is the place where Trusted Types API comes into play. With this API, all the insecure DOM API come to throws an error when a value is assigned, unless the value is created by `createHTML` method of a policy object.

```typescript
elemenet.innerHTML = 'Some malicious Code' // Throw an error
```

In other words, it can be considered trustworthy that all the HTML string created by `policy.createHTML()`, unless the policy object is global or available to anyone.

lit-html convert HTML strings into ones that are treated as trusted by `convertConstantTemplateStringToTrustedHTML()` function, with policy whose name is 'lit-html'.

```typescript
let policy: Pick<TrustedTypePolicy, 'createHTML'>|undefined;

function convertConstantTemplateStringToTrustedHTML(value: string): string|TrustedHTML {
  const w = window as any
  const trustedTypes = (w.trustedTypes || w.TrustedTypes) as TrustedTypePolicyFactory;
  if (trustedTypes && !policy) {
    policy = trustedTypes.createPolicy('lit-html', {createHTML: (s) => s});
  }
  return policy ? policy.createHTML(value) : value;
}
```

[Available policy name can be restricted via Content-Security-Policy (CSP) HTTP directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types) so the attackers cannot create policy by themselves.

This is how lit-html makes itself a secure HTML templating library.

But, as I said in the previous post, Trusted Types API is available only when polyfill or browser  run with flag for now. So `convertConstantTemplateStringToTrustedHTML()` function does nothing in most cases.

# Summary

So far, I learned the following points:

- All DOM API is by default insecure and sink of cross-site scripting
- Trusted Types API is proposed to solve this issue, but is still experimental.
- lit-html leverages Trusted Types API to make itself secure.

For further information about Trusted Types API, [Google's blog post](https://developers.google.com/web/updates/2019/02/trusted-types) will be helpful.

In the next post, I will look into `getHTML()` method of the `TemplateResult` class in more depth.