DEV Community

Nozomu Ikuta
Nozomu Ikuta

Posted on

Exploring How lit-html Works: TemplateResult and SVGTemplateResult constructors (2)

In this series, How lit-html works, I will explore (not explain) internal implementation of lit-html.

In the previous post, 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, 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 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.

elemenet.innerHTML = 'Some malicious Code' // Throw an error
Enter fullscreen mode Exit fullscreen mode

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'.

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;
}
Enter fullscreen mode Exit fullscreen mode

Available policy name can be restricted via Content-Security-Policy (CSP) HTTP directive 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 will be helpful.

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

Top comments (0)