Улучшить документацию Просмотреть исходный код $sce
- $sceProvider
- сервис в модуле ng
$sce — это сервис, предоставляющий AngularJS службы строгого контекстного экранирования.
Строгое контекстное экранирование
Строгое контекстное экранирование (SCE) — это режим, в котором AngularJS требует, чтобы привязки в определенных контекстах приводили к значению, помеченному как безопасно для использования в этом контексте. Одним из примеров такого контекста является привязка произвольного HTML, контролируемого пользователем через ng-bind-html. Такие контексты мы называем привилегированными или контекстами SCE.
Начиная с версии 1.2, Angular поставляется с включенным по умолчанию SCE.
Примечание: При включенном режиме (по умолчанию) не поддерживается IE<11 в режиме «quirks». В этом режиме IE<11 позволяет выполнять произвольный javascript с помощью синтаксиса expression(). Обратитесь к <!doctype html> в начало вашего HTML-документа.
SCE помогает писать код, который (а) по умолчанию является безопасным и (б) делает аудит на предмет уязвимостей, таких как XSS, clickjacking и т.д., намного проще.
Вот пример привязки в привилегированном контексте:
<input ng-model="userHtml" aria-label="User input"> <div ng-bind-html="userHtml"></div>
Обратите внимание, что ng-bind-html привязано к userHtml, контролируемому пользователем. При отключенном SCE это приложение позволяет пользователю отображать произвольный HTML в DIV. В более реалистичном примере можно отображать пользовательские комментарии, статьи блога и т. д. с помощью привязок. (HTML — это всего лишь один пример контекста, где отображение пользовательского ввода создает уязвимости безопасности.)
В случае с HTML вы можете использовать библиотеку на стороне клиента или сервера для очистки небезопасного HTML перед привязкой к значению и отображением его в документе.
Как вы можете гарантировать, что все места, где использовались эти типы привязок, были привязаны к значению, очищенному вашей библиотекой (или возвращённому как безопасно для отображения вашим сервером)? Как вы можете убедиться, что вы случайно не удалили строку, очищающую значение, или не переименовали некоторые свойства/поля и не забыли обновить привязку к очищенному значению?
Для обеспечения безопасности по умолчанию вы хотите убедиться, что любые такие привязки запрещены, если вы не можете определить, что что-то явно указывает на то, что значение безопасно для привязки в данном контексте. Затем вы можете проанализировать свой код (простой grep подойдёт) для того, чтобы убедиться, что это выполняется только для тех значений, которые вы легко можете определить как безопасные — потому что они были получены от вашего сервера, очищены вашей библиотекой и т. д. Вы можете организовать свою базу кода, чтобы помочь в этом — возможно, разрешая выполнять это только для файлов в определённом каталоге. Обеспечение того, что внутренний API, предоставляемый этим кодом, не маркирует произвольные значения как безопасные, становится более управляемой задачей.
В случае сервиса SCE AngularJS используется $sce.trustAs (и сокращённые методы, такие как $sce.trustAsHtml и т. д.), чтобы получить значения, которые будут приняты SCE/привилегированными контекстами.
Как это работает?
В привилегированных контекстах директивы и код будут привязаны к результату $sce.getTrusted(context, value), а не к самому значению напрямую. Директивы используют $sce.parseAs, а не $parse для отслеживания привязок атрибутов, которые выполняют $sce.getTrusted за кулисами для неконстантных литералов.
Например, ngBindHtml использует $sce.parseAsHtml(выражение привязки). Вот фактический код (несколько упрощённый):
var ngBindHtmlDirective = ['$sce', function($sce) {
return function(scope, element, attr) {
scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
element.html(value || '');
});
};
}];
Влияние на загрузку шаблонов
Это относится как к директиве ng-include, так и к шаблонам, определённым templateUrl директивами.
По умолчанию Angular загружает шаблоны только с того же домена и протокола, что и документ приложения. Это выполняется путём вызова $sce.getTrustedResourceUrl для URL-адреса шаблона. Для загрузки шаблонов с других доменных имён и/или протоколов вы можете либо добавить их в белый список, либо завернуть их в безопасное значение.
Обратите внимание: политика браузера Same Origin Policy и политика совместного использования ресурсов с другими доменам (CORS) дополнительно применяются и могут ещё больше ограничивать успешную загрузку шаблона. Это означает, что без соответствующей политики CORS загрузка шаблонов с другого домена не будет работать во всех браузерах. Также, загрузка шаблонов с file:// URL не работает в некоторых браузерах.
Это кажется слишком накладным
Важно помнить, что SCE применяется только к выражениям интерполяции.
Если ваши выражения являются константными литералами, они автоматически считаются безопасными, и вам не нужно вызывать $sce.trustAs (не забудьте включить модуль ngSanitize) (например, <div ng-bind-html="'<b>implicitly trusted</b>'"></div>) работает.
Кроме того, a[href] и img[src] автоматически очищают свои URL-адреса и не пропускают их через $sce.getTrusted. SCE здесь не играет никакой роли.
Включённый $sceDelegate поставляется с разумными значениями по умолчанию, позволяющими загружать шаблоны с домена вашего приложения без необходимости знать о SCE. Он блокирует загрузку шаблонов с других доменных имён или загрузку шаблонов по протоколу http из документа, сервер которого использует протокол https. Вы можете изменить эти значения, задав собственные пользовательские белые списки и чёрные списки для соответствия таким URL-адресам.
Это значительно снижает накладные расходы. Гораздо проще заплатить небольшую плату за накладные расходы и иметь приложение, которое является безопасным и может быть проверено на соответствие требованиям безопасности значительно легче, чем вносить изменения в приложение задним числом.
Какие типы безопасных контекстов поддерживаются?
| Контекст | Примечания |
|---|---|
$sce.HTML | Для HTML, который безопасно встраивать в приложение. Директива ngBindHtml использует этот контекст для привязок. Если встречается небезопасное значение и модуль $sanitize присутствует, он очистит это значение, вместо того, чтобы выбрасывать ошибку. |
$sce.CSS | Для CSS, который безопасно встраивать в приложение. В настоящее время не используется. Вы можете использовать его в своих директивах. |
$sce.URL | Для URL-адресов, которые безопасно использовать в качестве ссылок. В настоящее время не используется (<a href= и <img src= очищают свои URL-адреса и не являются контекстом SCE.) |
$sce.RESOURCE_URL | Для URL-адресов, которые не только безопасны для использования в качестве ссылок, но и содержимое которых безопасно включить в ваше приложение. Примеры включают ng-include, src / ngSrc привязки для тегов, отличных от IMG, VIDEO, AUDIO, SOURCE, и TRACK (например, IFRAME, OBJECT, и т. д.) Обратите внимание, что $sce.RESOURCE_URL делает более сильное заявление о URL-адресе, чем $sce.URL, и поэтому контексты, требующие значений, доверенных для $sce.RESOURCE_URL, могут использоваться везде, где требуются значения, доверенные для $sce.URL. |
$sce.JS | Для JavaScript-кода, который безопасно выполнить в контексте вашего приложения. В настоящее время не используется. Вы можете использовать его в своих директивах. |
Формат элементов в resourceUrlWhitelist/чёрном списке
Каждый элемент в этих массивах должен быть одним из следующих:
-
'self'
- Специальная строка,
'self', может использоваться для сопоставления со всеми URL-адресами того же домена, что и документ приложения, используя тот же протокол.
- Специальная строка,
-
Строка (кроме специального значения
'self')- Строка сопоставляется с полным нормализованным/абсолютным URL-адресом ресурса, который проверяется (сопоставление по подстроке недостаточно).
- Существует ровно две последовательности подстановок -
*и**. Все остальные символы соответствуют самим себе. -
*: соответствует нулю или более вхождениям любого символа, кроме одного из следующих 6 символов: ':', '/', '.', '?', '&' и ';'. Это полезная подстановка для использования в белом списке. -
**: соответствует нулю или более вхождениям любого символа. Поэтому она не подходит для использования в схеме, домене и т. д., так как сопоставит слишком много. (например, http://**.example.com/ будет соответствовать http://evil.com/?ignore=.example.com/, а это, возможно, не было целью.) Ее использование в самом конце пути допустимо. (например, http://foo.example.com/templates/**).
-
RegExp (см. замечание ниже)
-
Замечание: Хотя регулярные выражения мощные и предлагают большую гибкость, их синтаксис (и все неизбежные экранирования) делает их труднее поддерживать. Легко случайно ввести ошибку при обновлении сложного выражения (по-моему, все регулярные выражения должны иметь хорошую тестовую проработку). Например, использование
.в регулярном выражении верно только в небольшом количестве случаев. Символ.в регулярном выражении, используемом при сопоставлении схемы или поддомена, может быть сопоставлен с:или буквенным., что, вероятно, не предполагалось. Настоятельно рекомендуется использовать шаблоны строк и переходить к регулярным выражениям только в крайнем случае. - Регулярное выражение должно быть экземпляром RegExp (т. е. не строкой). Оно сопоставляется с целым нормализованным/абсолютным URL-адресом проверяемого ресурса (даже если в регулярном выражении не были указаны коды
^и$). Кроме того, любые флаги, присутствующие в RegExp (такие как многострочный, глобальный, регистронезависимый), игнорируются. - Если вы генерируете свой JavaScript из другого шаблонизатора (не рекомендуется, например, в вопросе #4006), помните о необходимости экранирования регулярного выражения (и будьте готовы к тому, что вам может потребоваться более одного уровня экранирования в зависимости от вашего шаблонизатора и способа интерполяции значения). Используйте механизм экранирования вашей платформы, так как он может быть достаточно хорош до написания собственного. Например, в Ruby есть Regexp.escape(str), а в Python — re.escape. В Javascript нет аналогичной встроенной функции для экранирования. Посмотрите на библиотеку Google Closure goog.string.regExpEscape(s).
-
Замечание: Хотя регулярные выражения мощные и предлагают большую гибкость, их синтаксис (и все неизбежные экранирования) делает их труднее поддерживать. Легко случайно ввести ошибку при обновлении сложного выражения (по-моему, все регулярные выражения должны иметь хорошую тестовую проработку). Например, использование
См. $sceDelegateProvider для примера.
Покажите пример использования SCE.
Могу ли я полностью отключить SCE?
Да, вы можете. Однако это настоятельно не рекомендуется. SCE предоставляет много преимуществ в плане безопасности с небольшими затратами на разработку. Будет намного сложнее взять приложение, в котором отключен SCE, и либо защитить его самостоятельно, либо включить SCE на более позднем этапе. Отключение SCE может быть оправдано в тех случаях, когда у вас много кода, написанного до появления SCE, и вы переносите его по модулям.
Тем не менее, вот как вы можете полностью отключить SCE:
angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
// Completely disable SCE. For demonstration purposes only!
// Do not use in new projects.
$sceProvider.enabled(false);
});
Использование
$sce();
Методы
-
isEnabled();
Возвращает логическое значение, указывающее, включен ли SCE.
Возвращаемое значение
Booleantrue, если SCE включен, false в противном случае. Если вы хотите установить значение, вам нужно сделать это во время конфигурации модуля на странице $sceProvider.
-
parseAs(type, expression);
Преобразует выражение Angular выражения в функцию. Это подобно $parse и идентично, когда выражение является литеральной константой. В противном случае оно оборачивает выражение в вызов $sce.getTrusted(type, result)
Параметры
Параметр Тип Подробности type stringТип контекста SCE, в котором будет использоваться этот результат.
expression stringСтроковое выражение для компиляции.
Возвращаемое значение
function(context, locals)функция, представляющая скомпилированное выражение:
-
context–{object}– объект, относительно которого вычисляются любые выражения, вложенные в строки (обычно объект области видимости). -
locals–{object=}– объект контекста локальных переменных, полезный для переопределения значений вcontext.
-
-
trustAs(type, value);
Делегирует вызов
$sceDelegate.trustAs. Таким образом, возвращает объект, которому Angular доверяет для использования в указанных строгих контекстах экранирования (например, ng-bind-html, ng-include, интерполяция атрибута src, интерполяция атрибута привязки события DOM, например, для onclick и т. д.), которые используют предоставленное значение. См. * $sce для включения строгого экранирования контекста.Параметры
Параметр Тип Подробности type stringТип контекста, в котором это значение безопасно для использования. Например, url, resourceUrl, html, js и css.
value *Значение, которое должно считаться надёжным/безопасным.
Возвращаемое значение
*Значение, которое может быть использовано для обозначения предоставленного
valueв местах, где Angular ожидает возвращаемого значения $sce.trustAs(). -
trustAsHtml(value);
Метод сокращённой записи.
$sce.trustAsHtml(value)→$sceDelegate.trustAs($sce.HTML, value)Параметры
Параметр Тип Подробности value *Значение для trustAs.
Возвращаемое значение
*Объект, который можно передать в $sce.getTrustedHtml(value) для получения исходного значения. (Директивы с привилегиями принимают только выражения, которые являются либо литеральными константами, либо результатом возвращаемого значения $sce.trustAs.)
-
trustAsUrl(value);
Метод сокращённой записи.
$sce.trustAsUrl(value)→$sceDelegate.trustAs($sce.URL, value)Параметры
Параметр Тип Подробности value *Значение для trustAs.
Возвращаемое значение
*Объект, который можно передать в $sce.getTrustedUrl(value) для получения исходного значения. (Директивы с привилегиями принимают только выражения, которые являются либо литеральными константами, либо результатом возвращаемого значения $sce.trustAs.)
-
trustAsResourceUrl(value);
Метод сокращённой записи.
$sce.trustAsResourceUrl(value)→$sceDelegate.trustAs($sce.RESOURCE_URL, value)Параметры
Параметр Тип Подробности value *Значение для trustAs.
Возвращаемое значение
*Объект, который можно передать в $sce.getTrustedResourceUrl(value) для получения исходного значения. (Директивы с привилегиями принимают только выражения, которые являются либо литеральными константами, либо результатом возвращаемого значения $sce.trustAs.)
-
trustAsJs(value);
Метод сокращённой записи.
$sce.trustAsJs(value)→$sceDelegate.trustAs($sce.JS, value)Параметры
Параметр Тип Подробности value *Значение для trustAs.
Возвращаемое значение
*Объект, который можно передать в $sce.getTrustedJs(value) для получения исходного значения. (Директивы с привилегиями принимают только выражения, которые являются либо литеральными константами, либо результатом возвращаемого значения $sce.trustAs.)
-
getTrusted(type, maybeTrusted);
Делегирует вызов
$sceDelegate.getTrusted. Таким образом, принимает результат вызова$sce.trustAs() и возвращает исходное значение, если тип запрошенного контекста является супертипом созданного типа. Если это условие не выполняется, генерирует исключение.Параметры
Параметр Тип Подробности type stringТип контекста, в котором будет использоваться это значение.
maybeTrusted *Результат предыдущего вызова
$sce.trustAs.Возвращаемое значение
*Значение, которое изначально было предоставлено
$sce.trustAs, если оно допустимо в данном контексте. В противном случае генерируется исключение. -
getTrustedHtml(value);
Метод сокращённой записи.
$sce.getTrustedHtml(value)→$sceDelegate.getTrusted($sce.HTML, value)Параметры
Параметр Тип Подробности value *Значение для передачи в
$sce.getTrusted.Возвращаемое значение
*Возвращаемое значение
$sce.getTrusted($sce.HTML, value) -
getTrustedCss(value);
Метод сокращённой записи.
$sce.getTrustedCss(value)→$sceDelegate.getTrusted($sce.CSS, value)Параметры
Параметр Тип Подробности value *Значение для передачи в
$sce.getTrusted.Возвращаемое значение
*Возвращаемое значение
$sce.getTrusted($sce.CSS, value) -
getTrustedUrl(value);
Метод сокращённой записи.
$sce.getTrustedUrl(value)→$sceDelegate.getTrusted($sce.URL, value)Параметры
Параметр Тип Подробности value *Значение для передачи в
$sce.getTrusted.Возвращаемое значение
*Возвращаемое значение
$sce.getTrusted($sce.URL, value) -
getTrustedResourceUrl(value);
Метод сокращённой записи.
$sce.getTrustedResourceUrl(value)→$sceDelegate.getTrusted($sce.RESOURCE_URL, value)Параметры
Параметр Тип Подробности value *Значение для передачи в
$sceDelegate.getTrusted.Возвращаемое значение
*Возвращаемое значение
$sce.getTrusted($sce.RESOURCE_URL, value) -
getTrustedJs(value);
Метод сокращённой записи.
$sce.getTrustedJs(value)→$sceDelegate.getTrusted($sce.JS, value)Параметры
Параметр Тип Подробности value *Значение для передачи в
$sce.getTrusted.Возвращаемое значение
*Возвращаемое значение
$sce.getTrusted($sce.JS, value)
-
parseAsHtml(expression);
Метод-сокращение.
$sce.parseAsHtml(expression string)→$sce.parseAs($sce.HTML, value)Параметры
Параметр Тип Подробности expression stringСтроковое выражение для компиляции.
Возвращаемое значение
function(context, locals)функция, представляющая скомпилированное выражение:
-
context–{object}– объект, по отношению к которому оцениваются любые выражения, вложенные в строки (обычно объект области видимости). -
locals–{object=}– объект контекста локальных переменных, полезный для переопределения значений вcontext.
-
-
parseAsCss(expression);
Метод-сокращение.
$sce.parseAsCss(value)→$sce.parseAs($sce.CSS, value)Параметры
Параметр Тип Подробности expression stringСтроковое выражение для компиляции.
Возвращаемое значение
function(context, locals)функция, представляющая скомпилированное выражение:
-
context–{object}– объект, по отношению к которому оцениваются любые выражения, вложенные в строки (обычно объект области видимости). -
locals–{object=}– объект контекста локальных переменных, полезный для переопределения значений вcontext.
-
-
parseAsUrl(expression);
Метод-сокращение.
$sce.parseAsUrl(value)→$sce.parseAs($sce.URL, value)Параметры
Параметр Тип Подробности expression stringСтроковое выражение для компиляции.
Возвращаемое значение
function(context, locals)функция, представляющая скомпилированное выражение:
-
context–{object}– объект, по отношению к которому оцениваются любые выражения, вложенные в строки (обычно объект области видимости). -
locals–{object=}– объект контекста локальных переменных, полезный для переопределения значений вcontext.
-
-
parseAsResourceUrl(expression);
Метод-сокращение.
$sce.parseAsResourceUrl(value)→$sce.parseAs($sce.RESOURCE_URL, value)Параметры
Параметр Тип Подробности expression stringСтроковое выражение для компиляции.
Возвращаемое значение
function(context, locals)функция, представляющая скомпилированное выражение:
-
context–{object}– объект, по отношению к которому оцениваются любые выражения, вложенные в строки (обычно объект области видимости). -
locals–{object=}– объект контекста локальных переменных, полезный для переопределения значений вcontext.
-
-
parseAsJs(expression);
Метод-сокращение.
$sce.parseAsJs(value)→$sce.parseAs($sce.JS, value)Параметры
Параметр Тип Подробности expression stringСтроковое выражение для компиляции.
Возвращаемое значение
function(context, locals)функция, представляющая скомпилированное выражение:
-
context–{object}– объект, по отношению к которому оцениваются любые выражения, вложенные в строки (обычно объект области видимости). -
locals–{object=}– объект контекста локальных переменных, полезный для переопределения значений вcontext.
-
© 2010–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.5.11/docs/api/ng/service/$sce