Open
Description
cc @koto @lukewarlow
This was initially opened in the wrong repo (web-platform-tests/wpt#49367) but to re-explain, this is about steps 5-8 in https://w3c.github.io/webappsec-csp/#can-compile-strings :
- Let sourceToValidate be a new TrustedScript object created in realm whose data is set to codeString if isTrusted is true, and codeString otherwise.
- Let sourceString be the result of executing the Get Trusted Type compliant string algorithm, with TrustedScript, realm, sourceToValidate, compilationSink, and 'script'.
- If the algorithm throws an error, throw an EvalError.
- If sourceString is not equal to codeString, throw an EvalError.
Main points:
- When isTrusted is true, these steps essentially do nothing ("Get Trusted Type compliant string" will return immediately with codeString) why are they ever needed?
- When isTrusted is false, this throws iff the createTrustedScript callback of the default policy actually modifies the value. This can be counter-intuitive (like it would continue execution with a lax policy that does not touch unsafe input while a strict policy that sanitize the code would likely throw) and I would expect something similar to https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#document-write-steps instead. But it seems it was something agreed with TC39 folks with the reasoning "if the string is not modified by the default policy it is likely because the input is safe". I guess it's fine security-wise, it's a stricter condition than always considering the sanitized string.
- https://github.com/web-platform-tests/wpt/pull/49449/files added some tests to check point 2. Obviously we cannot test the code for isTrusted=true since as I said it has no visible effect at all (besides the performance cost).
So for this issue the things we could do is to explicitly skip these steps (and simplify them) when isTrusted = true. And when isTrusted=false, maybe add a non-normative note explaining the rationale discussed with TC39 folks, so implementers are not surprised.