Comments (7)
I agree; the actual security Trusted Types would bring is directly dependent on being able to constrain unsafe creations. To distill the possible ways of addressing that:
-
Leave that out of the spec, but make it possible to guard creations in compilers / liters / static code analyzers. This is where the majority of Google JS code is nowadays. In addition to that, unsafe constructs should be greppable. We might change the name of the functions to
unsafelyCreateTrustedXYZ
like you suggested, that's a small improvement. -
Block unsafeCreation using a script-specific policy - e.g. CSP
trusted-types-src
source. I'd rather not bind ourselves to CSP just yet, but the idea of having a script-specific limitations is interesting, and we've looked into it as well. I imagine implementing script-specific constraints would be hard - @mikewest, WDYT? -
More fine-grained runtime limitations. This is something me and @slekies looked into. Some of the ideas may be implemented purely in JS, without any spec changes. For example:
(function(global, myOrigin) {
const createHTML = TrustedHTML.unsafelyCreate.bind(TrustedHTML);
const createScriptURL = TrustedScriptURL.unsafelyCreate.bind(TrustedScriptURL);
global.TrustedHTML.createSanitizedHTML = html => {
if (html.indexOf('<') == -1) {
return createHTML(html);
} else {
return createHTML(aDecentSanitizer.sanitize(html));
}
};
global.TrustedScriptURL.createWhitelistedURL = url => {
let u = new URL(url);
const whitelist = [
'https://third-party.example.com',
myOrigin
];
if (whitelist.indexOf(u.origin) !== -1) {
return createScriptURL(url);
}
throw new TypeError(`Origin of ${url} not whitelisted as TrustedScriptURL.`);
};
delete TrustedHTML.unsafelyCreate;
delete TrustedScriptURL.unsafelyCreate;
})(window, location.origin);
To facilitate locking down, we might want to expose an API to facilitate adding such app-specific, safe creation methods, with the function to lock down the setup completely (see e.g. koto/trusted-types@templatestrings-es6...koto:lockdown). This approach has the limitation of being runtime (so any code run before might be able to circumvent it), and, being in JavaScript, it doesn't propagate to new documents e.g. in iframes.
The lesson to take from GWT, is that maybe we should look into disallowing unsafe creations by default (Speaking in CSP terms, allowing them would require an unsafe-
prefix). That can't be done, however, if we don't offer ways in the platform to create a working application without them. We need to build in support for custom, "blessed", builders and allow a richer set of native safe builders.
from trusted-types.
FYI, I extracted the granular enforcement of types proposal into #33.
from trusted-types.
Re: propagating to iframes: I think it's OK to not propagate TrustedTypes enforcement to iframes: If the iframe is same-origin, its source is controlled by the same organization, and it's up to them to ensure that all their endpoints enable TrustedTypes. And if it's a different origin, it doesn't matter.
Re: globally disallowing unsafelyCreate
: Based on our experience, I don't think that's feasible in practice.
There are three broad categories of uses of unsafelyCreate
:
-
Use inside builders and frameworks. These uses establish the "core semantics" of the types (e.g., run-time predicates that recognize URLs that are considered safe in the context of a given application or group thereof; builders for TrustedHTML that support concatenation and construction of simple markup; contextually escaping HTML templating systems to construct complex markup).
-
Special-case uses throughout application code. These accommodate special cases required by a particular application. For example, functions that construct URLs to deep-link into mobile applications (e.g. via Android intents or custom schemes); these URLs are typically too specialized to include in standard library of builders. Of course, they could be factored out into application- or organization-specific libraries, but if there are only few call sites the added friction of doing so is undesirable.
-
"Legacy conversions" in existing code: When adapting existing code to use TrustedTypes (or Closure SafeHtml types), it's often necessary to refactor injection sinks in library APIs via multiple steps. To change an API that consumes a string that is passed to an injection sink (e.g.
.innerHTML
) to instead accept TrustedHTML, all its transitive callers need to be adjusted to actually supply that type. In large code-bases this can be difficult to do in a single atomic change. It is often more practical to change all immediate callers to (unsafely) convert whatever string they have to the required type, and then proceed outwards in separate changes. During large refactorings, we've found it useful to employ separate "legacy conversion functions". This distinguishes code that directly calls the "proper" unchecked conversion, and which should have been security-reviewed to be actually-safe, from legacy code that treats strings as HTML without security review (and which should be further refactored).
In a typical application, there should be only very few of (2) (say, a handful at most even in a fairly complex application), and none of (3) in newly developed code. Legacy code (gradually adopting the use of TrustedTypes) might have many of (3) however.
from trusted-types.
https://www.npmjs.com/package/node-sec-patterns is one way project maintainers can constrain which NPM modules mint values that encapsulate security guarantees via a minter/verifier model where the verifier is ambiently available but access to the minter is checked.
from trusted-types.
Regardless of the resulting API, there will be primitives available to user land code allowing to create trusted values (let's call them TT minters for analogy with https://github.com/mikesamuel/node-sec-patterns) i.e. values that would be allowed to be put into DOM even when TT enforcement is enabled. Those primitives will likely be references to functions - in the current iteration it's TrustedFoo.unsafelyCreate
references.
Either the platform features, or user land hardening code (which might be offered as a library) needs to guard the access to minters. Even if platform offers those, such methods need to be polyfillable, and should resist most known bypass methods - at least the ones that could not be detected at compile time.
https://github.com/mikesamuel/node-sec-patterns offers a way of guarding function references by:
- Using the node module loading and node packages meta data to store the information about the whitelisting.
- Using call-stack inspection to prevent calling the minter function from non-whitelisted callsites.
- Tracking meta information about minted instances in a WeakSet. Obtaining an instance of an object is not enough to bypass that check (it's stronger than
instanceof
, which can be bypassed withObject.create
. Only an instance that was minted will pass verification. - Lots of defensive programming - freezing instances, making properties not configurable etc.
So, in the end, the minter references are avaliable globally (after a given module is loaded), but access to them is protected at runtime. While we can not fully adopt all the checks (there's no client side package.json
equivalent), I think this offers a useful enhancement to a possible hardening library (or the polyfill for the native functionality). I would still like to be able to combine that with additional checks based on e.g. unavailability of the reference to the minter in a certain context, or that the minted value is an instanceof
something.
from trusted-types.
there's no client side package.json equivalent
Yeah. Not having a reliable name for a compilation unit makes things difficult.
ES6 modules are a bit better, but I don't know how easy it is to get from an ES6 module to a canonical name.
If we did have a way to reliably determine a name for a compilation unit, we could bootstrap something by looking for a whitelist under /.well-known
per RFC 5785.
That might make source-maps security-relevant though.
from trusted-types.
I believe this is implemented with the policy parts of the new API. Please reopen if something's missing.
from trusted-types.
Related Issues (20)
- Consider allowing `innerHTML = ''` HOT 18
- Bypass using execCommand HOT 5
- Create [TrustedTypes].fromLiteral method HOT 23
- Payable to
- Kpod
- Hash stash HOT 2
- @mikewest maybe `tonymade8` should be blocked? See also #352 and #351. HOT 1
- Add SVG <use> href attribute to Trusted Types enforcement HOT 17
- Maybe enforce Trusted Types in document.createProcessingInstruction?
- Maybe enforce Trusted Types in XSL's xsl:text HOT 5
- Can we conditionally enforce Trusted Types based on document response type in XHR? HOT 5
- Jquery Js getting reported error with TrustedTypes implementation HOT 1
- Figure out if there is a better way to guard navigations to `javascript:` across documents HOT 1
- Polyfill script link on w3c.github.io gives 404 HOT 1
- TrustedHTML.fromLiteral is exposed in workers but assumes the current global is a Window HOT 1
- Broken references in Trusted Types HOT 1
- should `null` & `undefined` for sinks requiring TT be a passthrough ? HOT 6
- TrustedTypes bypass using iframes HOT 4
- getAttributeType and getPropertyType should default to HTML namespace, not "" HOT 2
- 'Create a Trusted Type' algorithm returns error value in step 6 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from trusted-types.