w3c / trusted-types

A browser API to prevent DOM-Based Cross Site Scripting in modern web applications.
https://w3c.github.io/trusted-types/dist/spec/
Other
605 stars 74 forks source link

Maybe enforce Trusted Types in XSL's xsl:text #359

Open shhnjk opened 2 years ago

shhnjk commented 2 years ago

Currently, there is no Trusted Types enforcement on <xsl:text> in XSL document. Found by Alex https://twitter.com/kinugawamasato/status/1493641462776360961

<script>
  let attackerControlledString = "<img src=x onerror=alert(origin)>";
  const doc = document.implementation.createHTMLDocument();
  const xslt = document.createElementNS("http://www.w3.org/1999/XSL/Transform","xsl:stylesheet");
  xslt.setAttribute("xmlns:xsl","http://www.w3.org/1999/XSL/Transform");
  const template = document.createElementNS("http://www.w3.org/1999/XSL/Transform","xsl:template");
  template.setAttribute("match","/");
  const output = document.createElementNS("http://www.w3.org/1999/XSL/Transform","xsl:output");
  output.setAttribute("method","html");
  xslt.appendChild(output);
  const text = document.createElementNS("http://www.w3.org/1999/XSL/Transform","xsl:text");
  text.textContent = attackerControlledString;
  text.setAttribute("disable-output-escaping","yes");
  template.appendChild(text);
  xslt.appendChild(template);
  const processor = new XSLTProcessor();
  processor.importStylesheet(xslt);
  const fragment = processor.transformToFragment(doc,document);
  document.body.appendChild(fragment);
</script>
shhnjk commented 2 years ago

The actual root cause of XSS is due to disable-output-escaping attribute set to yes, which will disable HTML escaping. The only easy way to mitigate this bug seems to be disabling disable-output-escaping attribute under Trusted Types enforcement. Per this document, Firefox doesn't even support disable-output-escaping.

koto commented 2 years ago

XSLTProcessor.importStylesheet could also be a sink in this case, if the stylesheet nodes have a capability of causing script execution.

annevk commented 10 months ago

Yeah, XSLT entry points should be blocked. We shouldn't support XSLT in detail.

mbrodesser-Igalia commented 10 months ago

How would the entry points, e.g. XSLTProcessor.importStylesheet (https://developer.mozilla.org/en-US/docs/Web/API/XSLTProcessor/importStylesheet), be blocked?

This falls in class 3 of https://github.com/w3c/trusted-types/issues/419#issue-2098067918 and would require adapting the spec of importStylesheet (https://dom.spec.whatwg.org/#dom-xsltprocessor-importstylesheet). Be aware the latter lacks a definition (https://dom.spec.whatwg.org/#xslt).

I wonder if class 3 mentioned above will become large, with sinks like this. Requiring to change multiple specifications at a deeper level (in contrast to class 1).

mbrodesser-Igalia commented 10 months ago

The actual root cause of XSS is due to disable-output-escaping attribute set to yes, which will disable HTML escaping. The only easy way to mitigate this bug seems to be disabling disable-output-escaping attribute under Trusted Types enforcement. Per this document, Firefox doesn't even support disable-output-escaping.

Not sure whether Firefox indeed doesn't support it, since there's some code for it: https://searchfox.org/mozilla-central/search?q=disableOutputEscaping&path=&case=true&regexp=false. https://vulnerabledoma.in/ttbypass_XSLTProcessor.html causes an exception even without text.setAttribute("disable-output-escaping","yes");.