MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

開発のための Firefox セキュリティ基本

この翻訳は不完全です。英語から この記事を翻訳 してください。

対象読者

開発者、セキュリティに関係する人、Firefox セキュリティに関心のある人。

定義

Content - Web ページなどの信頼できないソースからロードされたもの(主にスクリプト)。セキュリティの討論では、'content' は Web コンテンツ内スクリプトにアクセスできるようにするための制限された権限セットを参照することができます。

Chrome - ブラウザに属する(Web コンテンツとは対立する)ものです。セキュリティの討論では、Chrome は全てのコードにアクセスできる権限セットを参照できます。(制限された Web コンテンツとは違います)

DocShell - ホストドキュメントのオブジェクトです。docshell は URI からコンテンツをロードする初期化処理を担い、コンテンツのビューアを作成し、コンテンツから受信したものをフックします。全てのウィンドウ(タブ)やフレームごとに関連した docshell が存在します。

Principal - セキュリティコンテキストです。Web では概して、スキーマ・ホストそしてポートの組み合わせになります。

Same-Origin Policy - ある origin からロードしたドキュメントやスクリプトが、他の origin のドキュメントのプロパティにアクセスることを防ぐためのポリシーです。

Sandbox - 制限された権限内で JavaScript コードを実行することを許可するオブジェクトです。通常の Web ページとして実行された場合、sandbox 内で評価されたコードは同じ権限を持ちます。

Wrappers - Wrapper はセーフガードや、Smae-Origin Policy のような基本的なセキュリティルールを強制することによって、信頼しないコンテンツから extionsion を保護します。

前提

このドキュメントでは、セキュリティ principal や共通の脆弱性、そして攻撃手法の前提知識があることを想定しています。言及しているコンセプトには、このドキュメントで記載している以上のコンセプトに関する情報が得られる外部リソースを参照するようにしています。

開発者は普段利用する技術に関連するセキュリティの落とし穴について熟知している必要があります。Web 開発者は XSS や CSRF について知っている必要があります。C++ であれば、バッファオーバーフローや書式文字列の脆弱性などについて知っている必要があります。

ゴール

Firefox で実行されるコードは以下のような外部コード(例えば Web ページで実行されている物など)を防ぐ必要があります。

  • Chrome 権限で実行されている物
  • ファイルシステムにアクセスするコード
  • 証明書を扱うコード
  • パーミッション無しで個人情報にアクセスするコード
  • (銀行などの)信頼されたページになりすましたコード
  • Firefox をクラッシュさせたり、利用不可能なものにするコード

ダウンロードして明示的に実行されたネイティブコードはユーザーを保護することができないことに注意してください。

フロントエンド

フロントエンドのセキュリティでは、Web セキュリティの習わしと同じくいくつかの方法があります。Firefox デスクトップでは UI は XUL になります(HTML に似たものです)。そこでは、センシティブな API 群を利用して(Firefoxの)バックエンドにアクセスするコードが含まれ、そのコードではコンテンツ(例えばブラウザを利用したドキュメントビュー)やユーザー(入力など)のデータなど信頼しないデータにアクセスすることができます。
  • 通常、コンテンツは chrome オブジェクトの参照を取得することができません。
  • content から chrome に対する XSS はやってはいけないです。Firefox 上のユーザーアカウントに関するすべての権限を持っているためです。これはリモートの攻撃コードを実行することができるようになり、黙ってインストールされるマルウェア(キーロガーなど)やパスワードマネージャのコンテンツを読み込むことなどができるようになってしまいます。
  • XUL と HTML の UI 要素の信頼しないデータを扱ううえでも注意すべきことがあります。innerHTML の扱いや createTextNode などの代わりとなるようなものを扱う事です。
  • Web コンテンツと chrome コードを実装する上で重要な違いは、iframe はデフォルトで chrome 権限を持つことです。もしそれを望まない場合(恐らくそれは望まない事でしょう)、コンテンツ上にそれを避けるために定義を書く必要があります。iframe.setAttribute("type", "content") です。

General

セキュリティチェック

一般的な状況下では、コンテンツをロードするときに、阻害するコードなどが含まれる異なるドメインのドキュメントを防ぐために、 Same Origin Policy が強制されます。

もし chrome から web コンテンツをロードするような状況に陥ったら、同じ処理を使って可能ならばすべてチェックするようにしたいと思うでしょう。もちろん principals 上でドキュメントを検証して、地震のチェックを実装する前に セキュリティチェックがされているか 確認できます。重複した処理は危険性をはらんでいます。この状況の場合、いくつかの理由から URL を直接扱う必要があり、そこにはいくつか気を付けないといけない落とし穴があります。(次のセクションを見てください。)

URI

URI を扱う際には以下の現象に注意を払ってください。

  • URI を操作する場合、ASCII のホスト名(例えば表示だけに用意されているような getASCIIHost から得られるホスト名)ではなく、直接 nsURI を使ってください。nsURI は標準に従った形式であるか保証するためです(nsIPrincipal は nsIURL のチェックしています)。
  • スキーマをチェックする際は、希望するスキーマの URI だけを許可するようにしてください。
  • Watch out for pseudoschemes -- in security checks it is the inner URI that is significant (e.g., jar:http://example.com -- http://example.com is the relevant part).
  • 全てをロードする前に、
    • ロードを許可するかチェックしてください。nsIScriptSecurityManagernsIPrincipal はリソースをロードするにあたって安全かどうかチェックする機能を提供しており、いつでも利用できます。ContentPolicy.shouldLoad も参照してください。
    • Web ページのリクエスト、またはリンクによってロードする場合、正しいリファラーを設定してください。しかし、ブックマークからロードする場合はリファラーを設定する必要はありません。

サンドボックス

サンドボックスは、明示的に Chrome 権限で実行する必要が無い Chrome コードを評価するときに利用します。(そして、スクリプトのコンテンツを完全に信頼します)

サンドボックスを作成して利用する:

// サンドボックスのインスタンスを生成する
var mySandbox = new Components.utils.Sandbox("http://www.example.com/");

mySandbox.y = 5;  // グローバルスコープの変数 'y' に 5 を代入

var result = Components.utils.evalInSandbox("x = y + 2; x + 3", mySandbox);
// result は 10, mySandbox.x は現在 7

サンドボックスに注入されたオブジェクトはサンドボックスの権限を継承しません。

しかし、サンドボックスがいの全ての関数は Chrome 権限で実行されます。

たとえば以下のコード:

var s = new Components.utils.Sandbox(url);
var x = Components.utils.evalInSandbox(untrusted_code, s);

Any method calls on x are unsafe, including the use of == which when evaluated will call the x.valueOf() method.

Interactions with content DOM

Firefox relies on wrappers to provide 'safe' representations of objects from one context in another (e.g., chrome from content and vice versa). In simple terms, wrappers can be thought of as filtering proxies which enforce the rules on how content and script from different principals may interact. For example, if a chrome object is exported to web content it will be wrapped in a ChromeObjectWrapper; this ensures that only the properties which are supposed to be exposed to web content (there's a whitelist in the __exposedProps__ property) can be accessed.

Whilst these wrappers provide a good level of protection against accidental problems, there are some things to be aware of. In particular, take care when using wrappedJSObject on content objects from chrome code (for more information on safely accessing content DOM from chrome, refer to this document).

More information on wrappers can be found in this article.

Chrome JS Dangerous functions

Avoid using eval or setTimeout(string, time) and other related functions if at all possible.

Further Reading:

ドキュメントのタグと貢献者

 このページの貢献者: mantaroh
 最終更新者: mantaroh,