trusted-types icon indicating copy to clipboard operation
trusted-types copied to clipboard

Rely on WedIDL's "implements" definition for isHTML/isScript/isScriptURL?

Open fred-wang opened this issue 11 months ago • 5 comments

cc @koto @lukewarlow @mbrodesser-Igalia

Initially suggested here: https://github.com/web-platform-tests/wpt/issues/49371#issuecomment-2500876097

See https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-ishtml

"Returns true if value is an instance of TrustedHTML and has an associated data value set, false otherwise."

and there is a note saying this allows to "check if a given object is truly a legitimate Trusted Type object (i.e. it was created via one of the configured policies)".

The CSP spec seems to do something similar but relies on implements instead. In that case we don't need to check if "the object has an associated data". So we the definition could be simplified as follows:

"Returns true if value implements TrustedHTML".

Browsers don't seem to check the presence of associated data, and I believe perform something that matches "implements":

Chromium: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc;l=301;drc=117bbc5c974e90bd7b28653649b4a59344bb22f0 Firefox: https://searchfox.org/mozilla-central/rev/fb8a1b0beee7dbc1b0a35050ec5c0345f0b09173/dom/security/trusted-types/TrustedTypePolicyFactory.cpp#159 WebKit: https://searchfox.org/wubkat/rev/c3d6184dbe8d3daa73c7c9201ce556cf81e35d3e/Source/WebCore/dom/TrustedTypePolicyFactory.cpp#85

BTW, I also believe these methods still return true for Trusted Type objects with forget toString mentioned on https://github.com/w3c/webappsec-csp/issues/697 that is Object.assign(policy.createScript("safe"), { toString: () => "unsafe" }). Maybe the note should mention that, maybe we should have tests too...

fred-wang avatar Dec 04 '24 11:12 fred-wang

BTW, I also believe these methods still return true for Trusted Type objects with forget toString mentioned on w3c/webappsec-csp#697 that is Object.assign(policy.createScript("safe"), { toString: () => "unsafe" }). Maybe the note should mention that, maybe we should have tests too...

They do, test e.g. https://jsbin.com/fiwewuqote/edit?html,console,output with Chrome.

ghost avatar Dec 05 '24 14:12 ghost

A potential security hole for this could be somePolicy.createScript(trustedtypes.isScript(someForgedObject) ? someForgedObject.toString() : "fallback");.

ghost avatar Dec 05 '24 14:12 ghost

@smaug---- @annevk @otherdaniel I wonder what you think about this? If that's ok, I guess I can send a spec PR.

fred-wang avatar Apr 09 '25 14:04 fred-wang

Yeah, "implements" or "is a" is the way to check a platform object's brand identity. (And these are platform objects by the time you are looking at them. IDL takes care of that.)

annevk avatar Apr 09 '25 14:04 annevk

We have a couple of instances of "instance of":

grep 'instance of' spec/index.bs 
:: Returns true if value is an instance of {{TrustedHTML}} and has an associated [=TrustedHTML/data=] value set, false otherwise.
:: Returns true if value is an instance of {{TrustedScript}} and has an associated [=TrustedScript/data=] value set, false otherwise.
:: Returns true if value is an instance of {{TrustedScriptURL}} and has an associated [=TrustedScriptURL/data=] value set, false otherwise.
1.  Return a new instance of an interface with a type
1.  If |input| is an instance of |expectedType|, return stringified
1. Assert: |convertedInput| is an instance of |expectedType|.
1.  Return a new instance of an interface with a type

I guess they can be replaced with https://webidl.spec.whatwg.org/#implements and https://webidl.spec.whatwg.org/#internally-create-a-new-object-implementing-the-interface

fred-wang avatar Apr 10 '25 08:04 fred-wang