$sce
- 概要
- getTrusted(type, maybeTrusted)
- getTrustedCss(value)
- getTrustedHtml(value)
- getTrustedJs(value)
- getTrustedResourceUrl(value)
- getTrustedUrl(value)
- parse(type, expression)
- parseAsCss(expression)
- parseAsHtml(expression)
- parseAsJs(expression)
- parseAsResourceUrl(expression)
- parseAsUrl(expression)
- trustAs(type, value)
- trustAsJs(value)
- trustAsResourceUrl(value)
- trustAsUrl(value)
- isEnabled()
- デモ
概要
$sceは、Strict Contextual EscapingをAngularJSに提供するサービスです。
Strict Contextual Escaping
Strict Contextual Escaping (SCE)は、AngularJSがそのコンテキストを使用するのに、 安全であると確立されたコンテキストを紐付けることを必須とするモードです。(翻訳に自信なし) そのようなコンテキストの例の1つに、ng-bind-htmlを通したユーザーによって制御される任意のHTMLの紐付けがあります。 これらのコンテキストを特権があるもの、またはSCEコンテキストとして参照します。
Angularのバージョン1.2から、デフォルトでSCEが有効になります。
注意: 有効になっている場合、IE8のQuirksモードではサポートされません。 このモードでは、IE8は任意のJavaScriptを「式()」文を使用することで実行することを許可してしまします。 詳細については、http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspxを参照してください。 HTMLドキュメントのトップに<doctype html>を追加することで、 ドキュメントが標準モードであり、Quirksモードでは無いことを確認することが出来ます。
SCEはデフォルトで、コードがセキュアな方法で書かれる手助けをし、(a) XSSやクリックジャッキングのようなセキュリティ脆弱性の検査を行います。(b) これは、非常に簡単に行うことが出来ます。
下記は特権コンテキストの紐付けの例になります。
<input ng-model="userHtml">
<div ng-bind-html="{{userHtml}}">
ng-bind-htmlは、ユーザーによって制御されるように{{userHtml}}に紐付けられている事に注目してください。 SCEを無効にすると、このアプリケーションは任意のHTMLをDIV内に描画することを許可します。 より現実な例ですと、紐付けを通してのブログ記事などのユーザーコメントなどの描画があるかもしれません。 (HTMLは、ユーザー入力によって作られるセキュリティ脆弱性の、描画コンテキストの1つの例に過ぎません。)
HTMLのケースでは、クライアントサイド上、またはサーバサイド上のどちらかで、 値の紐付けとドキュメント内の描画の前に、安全ではないHTMLのサニタイズにライブラリを使用するかもしれません。
どのようにして各場所で、これらのような形式の紐付けを、ライブラリを使用されて値がサニタイズされていることを保証しているのでしょうか? (または、サーバによって安全である描画として返しているのでしょうか?) どのようにして、誤ってサニタイズされた行を削除していない事、 またはあるプロパティ/フィールドの名前の変更と紐付けられているサニタイズされた値の更新を忘れていないことを保証できるのでしょうか?
デフォルトで安全であるために、「そのコンテキスト内で紐付けして使用する値が安全である」と判断できない限り、 そのような紐付けが禁止されていることを確認したいはずです。 そのため、サーバから受け取った、ライブラリでサニタイズされた等の理由で、 値が安全であるという事を簡単に伝えるための検査(簡単なものであればgrepを使って)することが可能です。(翻訳に自信なし) これを使用することで、特定のディレクトリ内のファイルのみを許可するといったことも可能になります。(翻訳に自信なし) 任意の値を使用しないコードによる安全な内部APIであることを保証すれば、作業はより管理しやすくなります。(翻訳に自信なし)
AngularJSのSCEサービスの場合、SCE/特権コンテキストによって受け入れられる値を取得するために、 $sec.trustAs(と、$sce.trustAsHtmlのような略記メソッド等)を使用します。
どのように動作するのか?
特権コンテキスト内のディレクティブとコードは、値を直接紐付けるのでは無く、 $sce.getTrusted(context, value)の結果を紐付けます。 ディレクティブは、属性の紐付けの監視に$parseでは無く、$sce.parseAsを使用し、 $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 || '');
});
};
}];
テンプレート読み込みの影響
これは、ディレクティブによって指定されたtemplateUrlの物はもちろんのこと、 ng-includeディレクティブの両方に適用されます。
デフォルトで、Angularは同じドメインとプロトコルのテンプレートのみを、アプリケーションドキュメントとして読み込みます。 これは、$sce.getTrustedResourceUrlにテンプレートURLを指定して呼び出すことによって行われます。 他のドメインまたはプロトコル、もしくはその両方から、テンプレートを読み込むために、 ホワイトリストに加えるか、信頼出来る値としてラップするかの、どちらかを行うことが可能です。
注意: ブラウザのSame Originポリシーと、 Cross-Origin Resource Sharing(CORS)ポリシーは、 これに付加される形で適用され、テンプレート読み込み成功の可否がより制限されるかもしれません。(翻訳に自信なし) これは、正しいCORSポリシー無しでは、異なるドメインからのテンプレート読み込みが、全てのブラウザ上で動作しない事を意味します。 また、file://形式のURLからのテンプレート読み込みも、ブラウザによっては動作しません。
SCEは開発者への負担が大きいのでは?
SCEは、補足するための式にのみ、適用されるという事を覚えておくことは重要です。
もし、式が定数リテラルの場合、それらは自動的に信頼出来るものとされ、それらに対して$sce.trustAsを呼び出す必要はありません。 (例: <div ng-html-bind-unsafe="'<b>信頼できる値<b&bt;'"><div>)
$sceDelegateが含まれると、デフォルトでSCEについての認識無しに、 アプリケーションのドメインからng-include内のテンプレート読み込みを許可します。(翻訳に自信なし) これは、異なるドメインからのテンプレート読み込み、またはhttpsからhttpを介してのテンプレート読み込みをブロックします。 ホワイトリストとブラックリストにURLを指定することで、これらの設定を変更することが可能です。
これは余計なオーバーヘッドを減らすために重要になります。 オーバーヘッドを少なくし、アプリケーションをセキュアにし、正当な値であるかの検査を行うために、 後からアプリケーション上でセキュリティチェックを行うよりも、この方法の方がはるかに容易です。
信頼出来るとして指定可能なコンテキストのタイプは?
コンテキスト | 説明 |
---|---|
$sce.HTML | アプリケーション内で安全なソースであるとするHTMLです。 ngBindHtmlディレクティブは紐付けに、このコンテキストを使用します。 |
$sce.CSS | アプリケーション内で安全なソースであるとするCSSです。 現在、Angular内では使用されていません。 ディレクティブを作成する際に必要に応じて使用してください。 |
$sce.URL | リンクとしても安全であるとするURLです。 現在、Angular内では使用されていません。 (<a href=と<img src= は、URLをサニタイズし、SECコンテキストを構成しません) |
$sce.RESOURCE_URL |
リンクとしては安全では無いが、URL先のコンテンツをアプリケーション内に含めても安全であるとするURLです。 例えば、ng-include、src/ngSrcを含んで紐付けを行うIMGタグ以外のものです。(例: IFRAME、OBJECT等) $sce.RESOURCE_URLは、$sce.URLより強い立場にあるため、$sce.RESOURCE_URLが必要とする信頼出来る値であるコンテキストは、 $sce.URLで必要とされる信頼出来る値であれば、何処にでも使用することが可能です。(翻訳に自信なし) |
$sce.JS | アプリケーションのコンテキスト内で実行しても安全であるとするJavaScriptです。 現在、Angular内では使用されていません。 ディレクティブを作成する際に必要に応じて使用してください。 |
resourceUrlWhitelist / Blacklistのフォーマットについて
これらの配列の各要素には、下記のいずれかが必要です。
例は、$sceDelegateProviderを参照してください。 SCEを使用した例が紹介されています。
getTrusted(type, maybeTrusted)
$sceDelegate.getTrustedへ委譲します。 そのため、$sce.trustAs()を呼び出し、もし、問い合されたコンテキストタイプが作成されたタイプのスーパータイプ(supertype)であった場合、 元の提供された値が返りその結果を取得します。 もしこの条件が満たされない場合、例外がスローされます。
引数 | 説明 |
---|---|
type |
型: この値が使用されているコンテキストの種類を指定します。 |
maybeTrusted |
型: 直前の$sce.trustAs呼び出しの結果を指定します。 |
戻り値 | 説明 |
型: もし、このコンテキスト内で有効である場合、$sce.trustAsに元々提供されていた値が返ります。 そうでなければ例外がスローされます。 |
© 2017 Google
Licensed under the Creative Commons Attribution License 3.0.
このページは、ページトップのリンク先のAngularJS公式ドキュメント内のページを翻訳した内容を基に構成されています。 下記の項目を確認し、必要に応じて公式のドキュメントをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。
- AngularJSの更新頻度が高いため、元のコンテンツと比べてドキュメントの情報が古くなっている可能性があります。
- "訳注:"などの断わりを入れた上で、日本人向けの情報やより分かり易くするための追記を行っている事があります。