user2899845
user2899845

Reputation: 1181

Sanitize untrusted CSS using Angular $sce.getTrustedCss

Trying to use $sce.getTrustedCss but always am getting an error for unsafe input.

Should such an example be safe or am I missing something.

$sce.getTrustedCss('.red {color: red;}');

Alternatively, are there other JS sanitizers that can work on CSS input?
google-caja only works for inline styling, it removes STYLE tags altogether.

Upvotes: 2

Views: 802

Answers (2)

Lee Goddard
Lee Goddard

Reputation: 11183

Since Angular 2, use DomSanitizer:

import { DomSanitizer } from '@angular/platform-browser';

constructor(
  private domSanitizer: DomSanitizer
) {}

// let legal = this.domSanitizer.bypassSecurityTrustStyle( styleAtrStr );

Upvotes: 1

Duncan
Duncan

Reputation: 95782

So far as I can tell, there is no actual CSS sanitization built in to Angular.

I think $sce.getTrustedCss(s) will always tell you that the input is unsafe unless you first do: s = $sce.trustAsCss(something). So if you pass your css through a sanitiser, or know it came from a trusted source you can mark it as safe for use.

Note also that the Angular documentation says that Angular doesn't actually use getTrustedCss() but you are free to use it in your own directives. I think that means if you do use it you would be responsible for ensuring the safe inputs were first passed through trustAsCss().

Here's the implementation of getTrusted():

function getTrusted(type, maybeTrusted) {
      if (maybeTrusted === null || isUndefined(maybeTrusted) || maybeTrusted === '') {
        return maybeTrusted;
      }
      var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
      if (constructor && maybeTrusted instanceof constructor) {
        return maybeTrusted.$$unwrapTrustedValue();
      }
      // If we get here, then we may only take one of two actions.
      // 1. sanitize the value for the requested type, or
      // 2. throw an exception.
      if (type === SCE_CONTEXTS.RESOURCE_URL) {
        if (isResourceUrlAllowedByPolicy(maybeTrusted)) {
          return maybeTrusted;
        } else {
          throw $sceMinErr('insecurl',
              'Blocked loading resource from url not allowed by $sceDelegate policy.  URL: {0}',
              maybeTrusted.toString());
        }
      } else if (type === SCE_CONTEXTS.HTML) {
        return htmlSanitizer(maybeTrusted);
      }
      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
    }

    return { trustAs: trustAs,
             getTrusted: getTrusted,
             valueOf: valueOf };
  }];

Notice that urls and html have some extra checking, but other types (css, js) are only trusted when have been wrapped by the appropriate trustAs... function. Also trustAsCss() doesn't appear to be documented, but as the shorthand methods are automatically generated it should exist (or you could use trustAs($sce.CSS, ...) directly).

Upvotes: 0

Related Questions