Code Monkey home page Code Monkey logo

Comments (7)

koto avatar koto commented on June 14, 2024

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:

  1. 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.

  2. 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?

  3. 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.

koto avatar koto commented on June 14, 2024

FYI, I extracted the granular enforcement of types proposal into #33.

from trusted-types.

xtofian avatar xtofian commented on June 14, 2024

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:

  1. 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).

  2. 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.

  3. "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.

mikesamuel avatar mikesamuel commented on June 14, 2024

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.

koto avatar koto commented on June 14, 2024

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 with Object.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.

mikesamuel avatar mikesamuel commented on June 14, 2024

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.

koto avatar koto commented on June 14, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.