Strict Contextual Escaping (SCE) disabled

ID

javascript.angular_contextual_escaping_disabled

Severity

critical

Resource

Misconfiguration

Language

JavaScript

Tags

Angular, AngularJS, CWE:79, NIST.SP.800-53, OWASP:2021:A3, PCI-DSS:6.5.7

Description

Angular (and the legacy Angular JS) has a security feature called Strict Contextual Escaping (SCE). SCE is a security feature that helps prevent Cross-Site Scripting (XSS) attacks.

When an application inserts data into the page using Angular’s interpolation mechanism, the output encoding is performed in the given context (HTML, JavaScript, CSS, URL…​) so that user input is properly escaped and cannot be executed in the JavaScript engine of the browser rendering the generated page.

When contextual escaping is disabled in Angular, it can lead to vulnerabilities such as Cross-Site Scripting (XSS) attacks. The detector checks for configurations globally disabling contextual escaping, and it also reports at the info level where it is disabled locally at specific points in the code.

Rationale

By default, Angular treats all values as untrusted and automatically escapes them when displayed in templates. This largely reduces the likelihood of XSS vulnerabilities, as it removes from the developers the burden of context-escaping values while embedding untrusted data in HTML templates.

Angular JS

The following example demonstrates how to disable SCE in Angular JS:

var app = angular.module('myApp', []);
app.config(function($sceProvider) {
    // FLAW - This disables SCE for the entire application
    $sceProvider.enabled(false);
});

By requiring explicit marking of values that are trusted to be safe HTML, CSS, URLs, and JavaScript, developers may selectively disable contextual escaping. This can be useful when partial support for HTML tags provided in the input is required, but input should be carefully whitelisted.

angular.module('app', [])
  .controller('controller', function($scope, $sce) {
    // Allowed, but reported at the info level
    $scope.myContent = $sce.trustAsHtml('<ul><li>' + item.toString() + '</li></ul>');
  });

Angular 2

Angular 2 uses a different security model that automatically sanitizes content to prevent XSS attacks. It does not allow to globally disable contextual escaping. Instead, the DomSanitizer service can be used to bypass encoding rules for specific content:

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

@Component({
  selector: 'app-example',
  template: `
    <div [innerHTML]="htmlContent"></div>
  `
})
export class ExampleComponent {
  htmlContent: any;

  constructor(private sanitizer: DomSanitizer) {
    const html = '<p>This is some <b>bold</b> text.</p>';
    // FLAW - possibly at the info level
    this.htmlContent = this.sanitizer.bypassSecurityTrustHtml(html);
  }
}

Remediation

Disabling globally SCE is dangerous and should be avoided, while locally disabling it at specific points in the code is acceptable but should be used with caution.

Note that while SCE provides security benefits, developers should still validate and sanitize input at the server level and avoid trusting user-provided content whenever possible. SCE should be used as part of a defense-in-depth security strategy, not as the sole protection against XSS.

Configuration

The following configuration options are available:

  • disallowSelectiveDisablingSCE: true | false - Set to true to disallow selectively disabling SCE for specific content. If false, occurrences will be reported at the info level. The default is false.

References

  • CWE-79 : Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

For current Angular, see:

For the now deprecated Angular JS, see: