Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Conversation

chirayuk
Copy link
Contributor

BREAKING CHANGE: Concatenating expressions makes it hard to reason about
whether some combination of concatenated values are unsafe to use
and could easily lead to XSS. By requiring that a single expression
be used for *[src/ng-src] such as iframe[src], object[src], etc.
(but not img[src/ng-src] since that value is sanitized), we ensure that the value
that's used is assigned or constructed by some JS code somewhere
that is more testable or make it obvious that you bound the value to
some user controlled value. This helps reduce the load when
auditing for XSS issues.

To migrate your code, follow the example below:

    Before:
        JS:
            scope.baseUrl = 'page';
            scope.a = 1;
            scope.b = 2;
        HTML:
            <!-- Are a and b properly escaped here? Is baseUrl
                 controlled by user? -->
            <iframe src="{{baseUrl}}?a={{a}&b={{b}}">

    After:
        JS:
            var baseUrl = "page";
            scope.getIframeSrc = function() {
              // There are obviously better ways to do this.  The
              // key point is that one will think about this and do
              // it the right way.
              var qs = ["a", "b"].map(function(value, name) {
                  return encodeURIComponent(name) + "=" +
                         encodeURIComponent(value);
                }).join("&");
              // baseUrl isn't on scope so it isn't bound to a user
              // controlled value.
              return baseUrl + "?" + qs;
            }
        HTML: <iframe src="{{getIframeSrc()}}">

BREAKING CHANGE: Concatenating expressions makes it hard to reason about
    whether some combination of concatenated values are unsafe to use
    and could easily lead to XSS.  By requiring that a single expression
    be used for *[src/ng-src] such as iframe[src], object[src], etc.
    (but not img[src/ng-src] since that value is sanitized), we ensure that the value
    that's used is assigned or constructed by some JS code somewhere
    that is more testable or make it obvious that you bound the value to
    some user controlled value.  This helps reduce the load when
    auditing for XSS issues.

    To migrate your code, follow the example below:

        Before:
            JS:
                scope.baseUrl = 'page';
                scope.a = 1;
                scope.b = 2;
            HTML:
                <!-- Are a and b properly escaped here? Is baseUrl
                     controlled by user? -->
                <iframe src="{{baseUrl}}?a={{a}&b={{b}}">

        After:
            JS:
                var baseUrl = "page";
                scope.getIframeSrc = function() {
                  // There are obviously better ways to do this.  The
                  // key point is that one will think about this and do
                  // it the right way.
                  var qs = ["a", "b"].map(function(value, name) {
                      return encodeURIComponent(name) + "=" +
                             encodeURIComponent(value);
                    }).join("&");
                  // baseUrl isn't on scope so it isn't bound to a user
                  // controlled value.
                  return baseUrl + "?" + qs;
                }
            HTML: <iframe src="{{getIframeSrc()}}">
@chirayuk chirayuk merged commit 38deedd into angular:master Jun 24, 2013
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants