Improve this Doc View Source

## Overview

The `ngProp` directive binds an expression to a DOM element property. `ngProp` allows writing to arbitrary properties by including the property name in the attribute, e.g. `ng-prop-value="'my value'"` binds 'my value' to the `value` property.

Usually, it's not necessary to write to properties in AngularJS, as the built-in directives handle the most common use cases (instead of the above example, you would use `ngValue`).

However, custom elements often use custom properties to hold data, and `ngProp` can be used to provide input to these custom elements.

## Binding to camelCase properties

Since HTML attributes are case-insensitive, camelCase properties like `innerHTML` must be escaped. AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so `innerHTML` must be written as `ng-prop-inner_h_t_m_l="expression"` (Note that this is just an example, and for binding HTML `ngBindHtml` should be used.

## Security

Binding expressions to arbitrary properties poses a security risk, as properties like `innerHTML` can insert potentially dangerous HTML into the application, e.g. script tags that execute malicious code. For this reason, `ngProp` applies Strict Contextual Escaping with the $sce service. This means vulnerable properties require their content to be "trusted", based on the context of the property. For example, the `innerHTML` is in the `HTML` context, and the `iframe.src` property is in the `RESOURCE_URL` context, which requires that values written to this property are trusted as a `RESOURCE_URL`.

This can be set explicitly by calling $sce.trustAs(type, value) on the value that is trusted before passing it to the `ng-prop-*` directive. There are exist shorthand methods for each context type in the form of $sce.trustAsResourceUrl() et al.

In some cases you can also rely upon automatic sanitization of untrusted values - see below.

Based on the context, other options may exist to mark a value as trusted / configure the behavior of `$sce`. For example, to restrict the `RESOURCE_URL` context to specific origins, use the trustedResourceUrlList() and bannedResourceUrlList().

Find out more about the different context types.

### HTML Sanitization

By default, `$sce` will throw an error if it detects untrusted HTML content, and will not bind the content. However, if you include the ngSanitize module, it will try to sanitize the potentially dangerous HTML, e.g. strip non-trusted tags and attributes when binding to `innerHTML`.

## Directive Info

- This directive executes at priority level 0.

## Usage

    <ANY ng-prop-propname="expression">
    </ANY>

or with uppercase letters in property (e.g. "propName"):

    <ANY ng-prop-prop_name="expression">
    </ANY>

## Examples

### Binding to different contexts

    angular.module('exampleNgProp', [])
    .component('main', {
      templateUrl: 'main.html',
      controller: function($sce) {
        this.safeContent = '<strong>Safe content</strong>';
        this.unsafeContent = '<button onclick="alert(\'Hello XSS!\')">Click for XSS</button>';
        this.trustedUnsafeContent = $sce.trustAsHtml(this.unsafeContent);
      }
    });

    <div>
      <div class="prop-unit">
        Binding to a property without security context:
        <div class="prop-binding" ng-prop-inner_text="$ctrl.safeContent"></div>
        <span class="prop-note">innerText</span> (safeContent)
      </div>

      <div class="prop-unit">
        "Safe" content that requires a security context will throw because the contents could potentially be dangerous ...
        <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.safeContent"></div>
        <span class="prop-note">innerHTML</span> (safeContent)
      </div>

      <div class="prop-unit">
        ... so that actually dangerous content cannot be executed:
        <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.unsafeContent"></div>
        <span class="prop-note">innerHTML</span> (unsafeContent)
      </div>

      <div class="prop-unit">
        ... but unsafe Content that has been trusted explicitly works - only do this if you are 100% sure!
        <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.trustedUnsafeContent"></div>
        <span class="prop-note">innerHTML</span> (trustedUnsafeContent)
      </div>
    </div>

    <main></main>

    .prop-unit {
      margin-bottom: 10px;
    }

    .prop-binding {
      min-height: 30px;
      border: 1px solid blue;
    }

    .prop-note {
      font-family: Monospace;
    }

### Binding to innerHTML with ngSanitize

    angular.module('exampleNgProp', ['ngSanitize'])
    .component('main', {
      templateUrl: 'main.html',
      controller: function($sce) {
        this.safeContent = '<strong>Safe content</strong>';
        this.unsafeContent = '<button onclick="alert(\'Hello XSS!\')">Click for XSS</button>';
        this.trustedUnsafeContent = $sce.trustAsHtml(this.unsafeContent);
      }
    });

    <div>
      <div class="prop-unit">
        "Safe" content will be sanitized ...
        <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.safeContent"></div>
        <span class="prop-note">innerHTML</span> (safeContent)
      </div>

      <div class="prop-unit">
        ... as will dangerous content:
        <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.unsafeContent"></div>
        <span class="prop-note">innerHTML</span> (unsafeContent)
      </div>

      <div class="prop-unit">
        ... and content that has been trusted explicitly works the same as without ngSanitize:
        <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.trustedUnsafeContent"></div>
        <span class="prop-note">innerHTML</span> (trustedUnsafeContent)
      </div>
    </div>

    <main></main>

    .prop-unit {
      margin-bottom: 10px;
    }

    .prop-binding {
      min-height: 30px;
      border: 1px solid blue;
    }

    .prop-note {
      font-family: Monospace;
    }