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
600 stars 70 forks source link

Trusted Types closure to replace fallback policy #462

Open lukewarlow opened 6 months ago

lukewarlow commented 6 months ago

Currently trusted types requires you to update each individual call site for specific policy usage OR you get one universal default policy.

This is, I suspect, in many cases not going to be suitable.

An idea would be to introduce some sort of closure to policies that lets you replace the fallback policy context inside of them.

const jqueryPolicy = trustedTypes.createPolicy('jquery', {...});

jqueryPolicy.run(() => {
    // Any code in here will use the jqueryPolicy instead of the default as a fallback.
    $("#example").html("Hello World");
});

This allows you to be as granular as you'd like given the restriction that don't have access to the callsite itself.

koto commented 6 months ago

We tried that approach with libraries on top of TT, but it just doesn't work, as one would have to wrap all the sinks. From what I remember the issue was that JS proxies don't mix well with the DOM element objects, and the approach was fruitless.

lukewarlow commented 6 months ago

Would the mechanism being internal fix those issues though? I'm not quite sure how proxies come into the picture?

koto commented 6 months ago
const delayedWriteToSink = (el) => setTimeout(() => el.innerHTML = 'bar');

policy.run(() => {
  delayedWriteToSink(el);
})

Elements inside the .run would have to be different than regular elements. The way to do it resembles what proxies were supposed to achieve.

lukewarlow commented 6 months ago

Wouldn't it be setting a context object and using that instead of default policy in the fallback method, rather than messing with elements directly?

Sora2455 commented 6 months ago

It's worth noting that jQuery specifically is updating itself to accept TrustedTypes as parameters to methods like .html(), so the example given might not be the best.

lukewarlow commented 6 months ago

Okay I can change it the concept is the same though code where the call site is inaccessible. Could be registering a custom element that does Dom manipulation as an example.