Lessons from open-source: Use window.trustedTypes to prevent DOM XSS.

Lessons from open-source: Use window.trustedTypes to prevent DOM XSS.

This lesson is picked from Next.js source code. In this article, you will learn what are window.trustedTypes.

I was looking at client/trusted-types.ts and found window.trustedTypes?.createPolicy. At first, I thought trustedTypes must be an Object set some wherelse in the Next.js code base, but after a quick search across the codebase, I didn’t find any such declaration. I made the next obvious move — “Google it”

I found the following useful resources:

  1. https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API

  2. https://web.dev/articles/trusted-types

  3. https://github.com/cure53/DOMPurify

  4. https://www.npmjs.com/package/trusted-types

The following image shows the files that use TrustedTypes.

Carefully looking at client/router-loader.ts tells me that script urls are sanitised before they are used in functions such as loadRoute and prefetch.

Here prefetch has a code snippet picked from GoogleChromeLabs shown below:

// https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
// License: Apache 2.0
let cn
if ((cn = (navigator as any).connection)) {
  // Don't prefetch if using 2G or if Save-Data is enabled.
  if (cn.saveData || /2g/.test(cn.effectiveType)) return Promise.resolve()
}

Conclusion

If the sanitization logic in DOMPurify is buggy, your application might still have a DOM XSS vulnerability. Trusted Types force you to process a value somehow, but don’t yet define what the exact processing rules are, and whether they are safe.” — this caution from web.dev makes me want to play around with TrustedTypes more and get a better understanding.

I found that Next.js source code uses Trusted types to sanitise the script urls before they are used in functions such as loadRoute and prefetch.

I also discovered that if you are using any code snippets from open source that are Apache 2.0 licensed, make sure you provide the attribution. Found this from prefetch function as it uses a code snippet from Google Chrome Labs used to detect if the user is on 2G or if Save-Data is enabled. Sheesh! I need to attain this level of supporting edge cases.