中級
この記事では、AIRセキュリティモデルの概要を紹介するとともに、このモデルの基となる考え方について解説します。
メモ:ユーザとアプリケーションデベロッパーの保護を目的としたAdobe AIRのセキュリティ規則およびコントロール群について詳しくは、Adobe AIR 1.0 セキュリティホワイトペーパーを参照してください。
Adobe AIRを利用すれば、すでにデベロッパーが身につけたHTML、Ajax、FlashまたはFlexのWeb開発スキルを生かしながら、デスクトップアプリケーションを開発・デプロイすることができます。ここでは、たとえWebテクノロジをベースにしているとはいえ、あくまでデスクトップアプリケーションの開発であるという点に注意が必要です。つまり、AIRの主なセキュリティモデルは、Webアプリケーションではなくデスクトップアプリケーションを前提としたものである必要があります。
デスクトップアプリケーションには、その独特の特徴がいくつかあります。たとえば、デスクトップアプリケーションはユーザによって特定のパソコンにインストールされるものであることから、不特定多数を対象とした、任意のWebコンテンツとは異なる次元の信頼性が暗黙に了解されています。このため、一般的には同様のWebアプリケーションより多くの権限が付与されます。しかしこの一方で、デスクトップアプリケーションが提供する各種権限を使用するにあたっては、一層入念な注意が必要となります。これは、Webアプリケーションでは一般的であっても、デスクトップアプリケーションでは考えられないようなコード記述テクニックやパターン仕様があるからです。
AIRアプリケーションは、FlashおよびHTML/Ajaxの組み合わせを利用して開発できます。 また、ドキュメントのレンダリング時にはPDFを利用することも可能です(ただし、PDFファイルのみをAIRアプリケーションのベースにすることはできません)。
アプリケーションが主にFlash、HTMLのどちらをベースに開発されているかを問わず、AIRアプリケーションには、すべて共通の特徴があります。各AIRアプリケーションには、通常、ブラウザ内で実行されるWebアプリケーションからは利用できないAIR独自のAPI群が用意されており、これらを利用することでローカルシステムやネットワークリソースへのアクセスが可能になります。また、個々のAIRアプリケーションには、読み込まれるコンテンツの種類と用途に応じた複数のサンドボックスが含まれています。
app:/ URIスキームを介して)ダイレクトに読み込まれたコンテンツのみを配置することができます。AIRのサンドボックスについて詳しくは、HTMLおよびAjaxを使用したAdobe AIRアプリケーション開発のサンドボックスの節を参照してください。
Webアプリケーションで一般化した設計・実装手法でも、AIRアプリケーションサンドボックスが許可するローカルシステムへのアクセスと組み合わせるには危険すぎるものがあります。デスクトップアプリケーションの場合、ユーザがアプリケーションをダウンロードし、インストール・実行する行為によって、ユーザは(明確に認識されていないケースがあるものの)当該アプリケーションにシステムへのアクセスを許可します。つまり理論上は、インストールおよび初めての起動に先だって、ユーザには当該アプリケーションを検証・承認する機会が与えられているのです。
また、仕組み上、リモートサーバから読み込んだコードを実行したり、黙示的かつダイナミックに追加コンポーネントをインストールして、アプリケーションの機能性を拡張することは制限されています。 たとえば、デスクトップ開発の基本事項として、インストール済みのアプリケーションにアップデートやプラグイン、他の拡張機能などをダウンロード・インストールする際には、ユーザにその旨を通知することが慣習化されています。このような処理が自動的に行われているかのように見えるアプリケーションでも、何らかの形でユーザへの通知が行われているとともに、自動アップデートを無効化するための設定オプションが用意されています。ユーザの同意を得ずに処理を行うアプリケーションは、プライバシーの侵害にとどまらず、セキュリティ上の脆弱性があるアプリケーションとも捉えられる恐れがあります。このような事情からも、アプリケーションサンドボックスでは、リモートコンテンツからの実行スクリプトの読み込みが禁じられています。
次のようなケースを考えてみてください。仮に、今日の株価チャートを表示するために、あるいは最新のアプリケーション機能を提供するために、デスクトップアプリケーションがその都度、Webサイトからスクリプトを自動的に読み込むとしたらどうなるのでしょうか。 この場合、サーバに不法なアクセスがあったり、コードの読み込みが毎回入念に処理されていない場合(つまり、当該スクリプトの証明書に署名し、その署名の有効性を検証するようにしていない場合)は、スクリプトがホスティングされたサーバに攻撃者が侵入するだけで、当該アプリケーションを実行するすべてのマシンが制御できるようになってしまいます。つまり、ユーザがアプリケーションをインストールすることによって、そのアプリケーションに追加コードのダウンロード・実行が自動的に許可されるのではありません。このようなケースでは、ユーザの意図的な同意を追加で得る必要があります。
もう1つの検討事項としては、アプリケーションが外部コードやスクリプトの読み込みを指示していないにもかかわらず、デベロッパーの意図に反して、リモートスクリプトの混入(クロスサイトスクリプティング脆弱性またはXSSとして知られています)を許してしまうケースが挙げられます。 この問題が生じる一般例としては、JavaScriptのeval()関数を使用するケースがあります。eval()関数はテンプレートと、リモートドメインから読み込まれ得るデータを組み合わせて、コードを生成するために用いられることがよくあります。あらゆる形のコード混入を想定して、デベロッパーが読み込まれたデータを非常に入念に除去しない限り、アプリケーションサンドボックス内でeval()が実行されると、悪質なコードを含むデータによってユーザシステムが攻撃対象となる恐れがあります。 このような理由からも、実行時のコード生成のためにアプリケーションサンドボックス内でeval()および同様のAPIを使用することは禁じられています。
最後の注意事項は、AIR独自のAPIにおいてリモートデータを使用するケースです。このケースでは、極度の注意が必要とされます。仮にリモートサーバが、アプリケーションによってダウンロードされるファイルのファイル名とその中身を提供できるのであれば、当該ファイルは、ファイルシステムの機密部分にも書き込めることとなり、この結果、悪質なルートキットがインストールされるような事態も否定できません。やや強引な結論だと感じられる読者もおられるかと思いますが、この誤りは、たとえデベロッパーが十分注意していたとしても陥りやすい、よくある問題の1つとして挙げられます。仮に、ユーザがリモートサーバ上の写真を閲覧・保存できるようなアプリケーションを開発したとしましょう。この場合、アプリケーションのどこかで、以下に示すような関数を使用することが想定されます。
savePhoto(var filename, var content);
また、もう一歩踏み込んで(たとえば)ルートディレクトリの指定を行っていたともします。 C:\Photos— これをファイル名の変数の冒頭に付け加えていたとします。次のようなデータがリモートサーバによって提供されたケースを想像してみてください。
filename = "sailboat.jpg"
content = <contents of an actual JPEG>
コードの冒頭には C:\Photosが追加され、この結果が次のようになります。
filename = "C:\Photos\sailboat.jpg"
一見、問題がないように見えますが、仮にリモートサーバが次のようなデータを提供するとしたら、どうでしょう。
filename = "..\Windows\notepad.exe"
content = <contents of an EXE rootkit>
ファイル名にルートディレクトを付け加えると、次のような体裁になります。
Filename = "C:\Photos\..\Windows\notepad.exe"
この場合、Windowsディレクトリのメモ帳アプリケーションが上書きされることになり、この結果、ユーザが次にメモ帳を起動しようとすると、ルートキットが実行されてしまいます。 ここでは単純な例を挙げて解説しましたが、このような誤りが、いかに簡単に犯し得るかがおわかりいただけたかと思います。
さらに詳しい情報については、Adobe Flex 3を使用したAdobe AIRアプリケーション開発のデベロッパーのためのセキュリティベストプラクティスの節およびディスクへの書き込みの節を参照してください。
AIRのHTMLアプリケーションサンドボックスのセキュリティモデルは、ブラウザに用意されているそれとは大きく異なります。 この理由は、HTML Webアプリケーションの開発で一般化したデザイン・実装手法の中には、AIRのアプリケーションサンドボックスが許可するローカルシステムへのアクセスと組み合わせるには危険すぎるものがあるからです。
たとえば、リモートからのスクリプト読み込み、eval()を介した動的なスクリプト生成、innerHTMLおよびouterHTML DOM要素へのコード投入といった手法は、その使用が危険であるにもかかわらず、HTMLアプリケーションで広く普及しています。しかし、すでに普及しているからといって、これらのテクニックがAIRのアプリケーションサンドボックスで許可されるわけではありません。アプリケーションサンドボックス上でスクリプトを読み込んだり、ダイナミック的にコードを生成しようとすると、さまざまな制約があることに気付くはずです。危険を伴うこれらの実行手法の実装が避けられない場合は、(後ほど解説の)非アプリケーションサンドボックスを利用する必要があります。
HTMLセキュリティモデルには、いくつかの驚くべき特徴があります。たとえば、セキュリティサンドボックスの最も適用範囲が広いものとして、フレーム全体(frame、iframeおよびwindow)があります。つまり、この場合、フレーム内のコードはすべて同じサンドボックスに属することになり、コードがどのようにしてフレームに読み込まれたかにかかわらず、すべて同一の権限が付与されることになります。ブラウザ(およびAIR)は、ページに元から配置されているコードと、eval()関数によって生成され、ページ外から読み込まれたコードを区別することができません。このため、信頼できるコンテンツとそれ以外を安全に処理するには、当該コンテンツを別々のフレームまたはサンドボックスに配置する方法が唯一の対応策となります。
詳しい情報については、HTMLおよびAjaxを使用したAIRアプリケーション開発のHTMLセキュリティの節、ならびにHTMLセキュリティFAQを参照してください。
ダイナミックなコーディングおよびスクリプト読み込みが制限されていることから、アプリケーションサンドボックスは典型的なブラウザサンドボックスと比べてもコード混入攻撃のリスクが大幅に小さく、一般的にアプリケーションコードを配置するにあたって最も安全なサンドボックスだといえます。しかし、場合によっては、デベロッパーがアプリケーションにおいて、これらの危険なテクニックの使用を避けられないケースもあります。たとえば、JSON非対応のJavaScript APIのみをサポートするWebサービスと通信しなければならないケースがこれにあたります。
このようなケースでの推奨テクニックは、非アプリケーションサンドボックスを作成して危険の伴う操作を行い、そしてSandboxBridge APIを介してこのサンドボックスとやりとりを行う手法です。 SandboxBridgeは、通常お互いを信頼することのないドメイン間・サンドボックス間での通信を可能にする、双方向型のシリアライゼーションAPIです。
プラグインなどのアプリケーション拡張機能は、このSandboxBridgeを介して実装するのが最適です。ユーザの同意を得てから、プラグインを非アプリケーションの位置(app-storage:など)に格納し、これを非アプリケーションサンドボックスに読み込むことができます。適切な定義が行われたプラグインAPIを公開することで(ブラウザプラグインに対するNPAPIの機能のように)、当該プラグインをアプリケーションサンドボックスに読み込むことなく、自らが開発したプラグインはもちろん、読者のアプリケーション用としてサードパーティが開発したプラグインとも安全に通信できるようになります。適切な定義が行われたプラグインAPIはセキュリティの観点から望ましいだけでなく、アプリケーションの将来のアップデート時に、プラグインが破損するリスクを低減する効果もあることから、より安定性に優れたソリューションといえます。
SandboxBridgeは、「安全装置」の用意された機能ではない点に注意するようにしてください。アプリケーションサンドボックス内のコードがSandboxBridgeを介し、任意のリモートコードによる呼び出しが安全ではないAPIを公開するような事態を避けるように注意が必要です。したがって、システムAPIや重要なアプリケーションAPIは、SandboxBridgeを介してダイレクトに公開しないようにすることが重要です。
しかし、eval()関数を非アプリケーションサンドボックスからアプリケーションサンドボックスに対して公開することは可能です。これは、公開されたeval()関数内で評価されるコードが、非アプリケーションサンドボックスの文脈において実行されるからです。この場合、機密的なAPIやアプリケーションデータへのアクセスは許可されません(当該の非アプリケーションサンドボックスに対してこれらを公開済みである場合は、この限りではありません)。一般的なルールとしては、非アプリケーションサンドボックスからアプリケーションサンドボックスへの関数やデータの公開は可である一方、アプリケーションサンドボックスから非アプリケーションサンドボックスへの関数やデータの公開は、危険が伴うと理解することができます。したがって、これらの危険なテクニックのために特定の非アプリケーションサンドボックスを使用する場合は、信頼性を欠くものに対して利用することを避けるとともに、機密的なデータやAPIを提供しないようにすることが重要です。
SandboxBridgeの使用について詳しくは、HTMLおよびAjaxを使用したAdobe AIRアプリケーション開発の信頼できないコンテンツの安全な扱い方の節を参照してください。
通常、AIRアプリケーションは次の2つの方法でインストールされます。
どちらのケースでも、AIRアプリケーションのインストール時に提供されるユーザ体験はほぼ同じです。注目に値する唯一の相違点といえば、アプリケーションが一般に認められた商用のコード署名証明書で署名されているか、無償の自己署名証明書で署名されているかの違いだけです。
いずれのケースでも、インストールの手続き時には.airファイルのダウンロードが発生します。.airファイルは、HTML、SWF、JavaScriptおよびその他の種類のファイルを含めることができる、ZIPファイルの変種に過ぎません。したがって、既存のセキュリティツールのほとんどが.airファイル自体、またはインストール手続き中や実行時に抽出されるファイル群を検証することができます。
シームレスなインストールバッジ機能の活用例については、AIRデベロッパーセンターのAIRサンプルアプリケーションを参照してください。
AIRアプリケーションはすべて、コード署名証明書によって署名される必要があります。証明書には2種類があり、1つは自己署名証明書と呼ばれるもの、そしてもう1つは主要認証機関(CA)より購入できる商用のコード署名証明書です。自己署名型の証明書の場合、(ユーザが意図的に当該の証明書を信頼できるものとして登録しない限り)一般ユーザのマシン環境では、その信頼性が認められたものとは解釈されません。
ここでは商用のコード署名証明書を入手することが推奨されます。商用のコード署名証明書は、ほぼすべてのユーザマシン上のAIRインストーラによって認識されます。この方法をとることで発行者名が認識できるようになり、ユーザに対して、より円滑なインストール体験を提供できるようになります。
AIRアプリケーションのコード署名について詳しくは、Adobe LiveDocのAdobe Flex 3を使用したAPIアプリケーション開発、およびTodd Prekaski氏執筆の別途記事、Adobe AIRアプリケーションのデジタル署名を参照してください。
デスクトップアプリケーションランタイムであるからこそ、AIRのセキュリティモデルはWebブラウザのそれとは大きく異なります。AIRのアプリケーションサンドボックスはシステムAPIへのダイレクトアクセスを提供する一方で、いくつかのAPIに対しては制限や禁止事項が設けられています。中でも、アプリケーションサンドボックス内での非アプリケーション型コンテンツ(app:/経由で読み込まれないもの)の読み込みやコードのダイナミック生成に関しては、厳しい制約が課されています。
大半のケースでは、フレームワークや既存コードを編集なし、または若干編集するだけでアプリケーションサンドボックスで利用することができます。しかし、一部のデベロッパーは、リスクの伴う操作(リモートJavaScriptの読み込みなど)を避けられないことがあります。この場合は非アプリケーションサンドボックスで当該操作を行い、その後SandboxBridge APIを介して、結果のコードやデータを注意しながらアプリケーションサンドボックスへと公開するようにします。
純然たるデスクトップアプリケーションだからこそ、デベロッパーにはさまざまな権限が与えられます。このため、本記事で紹介した制約事項の回避策を見いだすことは不可能ではないかも知れません。しかし、このようにして見つけた回避策を実装した場合、アプリケーションおよびそのエンドユーザに対しては、新たに、重大なセキュリティリスクを提供してしまうことが避けられないといえるでしょう。このためアドビでは、デベロッパーに対して、AIRのセキュリティモデルに設けられた制約事項を厳守することを強くお勧めするとともに、独自の回避策の導入にあたっては、十分なセキュリティ対策を実装するために必要な費用や手間についても、入念に検討を重ねることを推奨します。これらのセキュリティ対策を開発するための費用の方が、規定のセキュリティモデルを守りつつ、他の代替ソリューションを見いだすのにかかる費用より、格段に高価になるケースがほとんどです。
Tutorials and samples |
AIR blogs |
More |
AIR Cookbooks |
More |
| 01/20/2012 | Skinnable Transform Tool |
|---|---|
| 01/18/2012 | Recording webcam video & audio in a flv file on local drive |
| 12/12/2011 | Date calculations using 'out-of-the-box' functions |
| 11/29/2011 | Button compatibility with NativeComboBox |