Web Player のトラストチェーンを使用する
Web Player のトラブルシューティング

Webplayer のセキュリティサンドボックス

Unity3.0 以降では、Webplayer は Adobe Flashplayer で使用されているものと類似したセキュリティモデルを実装しています。このセキュリティの制限はビルドターゲットを Webplayer に設定しているときおよび Webplayer に適応されます。セキュリティモデルは、いくつかの段階があります。

  • unity3d をホストしているドメイン以外のドメイン上のデータへのアクセスを制限する
  • ソケットの使用にいくつかの制限がある
  • いくつかのメソッドを使用できない
  • あなたが記述していないクラスやメソッドに対する System.Reflection.* の使用を制限

最初の二つの項目はエディターでエミュレートされます。メソッド/クラスが Web Player で利用できる一覧は こちら を参照してください。

Unity のマルチプレイヤーネットワーキングを実現する機能( UnityEngine.NetworkUnityEngine.NetworkView クラス等)は影響を受けません。

このドキュメントは Unity Web Player バージョン 3.0 での動作を確認する方法について記述します

WWW のクラスとソケットは、同じポリシー・スキーマを使用していますが、彼らは完全に独立したシステムです。WWW のポリシーは、ポリシーがホストされた Web サービスにアクセスを許可していますが、ソケットポリシーは、すべての TCP / UDP ソケット接続に適用されます。

Unity エディターは“Web Security エミュレーター”機能が付属しています。これは Web Player にセキュリティモデルを課します。 これにより比較的簡単に問題を検出することができます。この設定は、下の項目から見つける事ができます。 Edit->Project Settings->Editorエディター設定 も参照してください。

WWW クラスを使用する際の考慮事項

Unity の web player は crossdomain.xml という http でのポリシーファイルが WWW クラスによりアクセスするドメイン上で利用可能であることが必要です。 (ただし Unity3d ファイルをホストしているのと同じドメインである場合は必要ありません)

例えば、テトリスゲームを想像してください。次の URL をホストしている場合、

http://gamecompany.com/games/tetris.unity3d

次の URL からハイスコアリストにアクセスする必要があります。

http://highscoreprovider.net/gethighscore.php

このケースでは、highscoreprovider.net や類似のドメインに crossdomain.xml を配置する必要があります:’http://highscoreprovider.net/crossdomain.xml’’

crossdomain.xml ファイルの内容は Flash Player で使用される形式になっています。 `crossdomain.xml@@ ファイルはすでに配置されている可能性が高いです。ファイルに記述されているポリシー以下のとおりです。

<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>


ファイルを http://highscoreprovider.net/crossdomain.xml に配置する際、 ドメインのオーナーは webserver のコンテンツがさまざまなドメインからアクセスされるかもしれない事を宣言します。

Unity の Webplayer は <allow-http-request-headers-from domain><site-control permitted-cross-domain-policies> タグをサポートしていません。crossdomain.xml は ASCII ファイルでなければならないことに注意してください。

デバッギング

環境変数 ENABLE _CROSSDOMAIN_ LOGGING1 に設定すると、Unity ランタイムが crossdomain.xml ファイルをフェッチしてデコードするにつれてコンソールメッセージが生成されます。Mac 上ではグローバル環境変数を /etc/launchd.conf で設定できます。PC 上では Control Panel->System And Security->System->Advanced system settings->Environment Variables… から変更します。

この環境変数を設定し、Web Player がリモートサーバーから画像をフェッチを試みた際の出力例を次に示します。

Determining crossdomain.xml location for request: http://www.remoteserver.com/image.jpg
About to parse url: http://www.remoteserver.com/image.jpg
Determining crossdomain.xml location for request: http://www.remoteserver.com/image.jpg
About to parse url: http://www.remoteserver.com/crossdomain.xml
About to parse url: http://www.remoteserver.com/image.jpg
Determining crossdomain.xml location for request: http://www.remoteserver.com/image.jpg
Download had OK statuscode
Received the following crossdomain.xml
--------------------------------------
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>
----------------------
received policy
Parsing: cross-domain-policy
cross-domain-policy
Parsing: allow-access-from
allow-access-from
  domain: *
done parsing policy
crossdomain.xml was succesfully parsed
About to parse url: http://www.remoteserver.com/image.jpg
Checking if http://www.remoteserver.com/image.jpg is a valid domain
Checking request-host: www.remoteserver.com against valid domain: *
All requirements met, the request is approved


エディターを実行するとき、これらのメッセージは Editor.log に書き込みされます。utf16BOM ありで格納された crossdomain.xml の読み込みが失敗すると XML のパースに失敗につながります。

BuildFlashPolicy caught an exception while parsing http://www.remoteserver.com/crossdomain.xml: Expected element


BOM ありは予想されていないため失敗します。サポートされていない BOM なし utf16 ファイルを使用すると次の結果となります。

BuildFlashPolicy caught an exception while parsing http://www.remoteserver.com/crossdomain.xml: Policy can't be constructed from empty stream.


これはファイルの最初のバイトが 0 であり、パーサーがファイルの終わりに到達したと考えてしまうためです。Crossdomain.xml は ASCII ファイルである必要があります。

ソケットを使用する際の考慮事項

Unity の web player は特定のホストに接続するために、ソケットサーバーポリシーを必要とします。このポリシーはデフォルトではポート 843 のターゲット干すとによってホストされていますが、それは同様に他のポート上でホストすることができます。デフォルトとデフォルト以外の機能的な違いは、それを手動で取得する必要がある事です。Security.PrefetchSocketPolicy() API を呼び出し、それが 1024 より大きいポート上でホストされている場合のみ、ポリシーが 1024 より大きい他のポートへのアクセスを与える事ができます。

デフォルトのポートを使用する場合、Unity Webplayer は TCP ソケットの接続を確立させようとホストサーバーが接続を受け入れるか確認します。 これは、新しい接続を介してソケットポリシーを受信することを期待し、ポート 843 の TCP ソケットを開く事で行います。Unity の web player はホストと接続を行い、エラー無しで接続され接続が許可されていることを確認します。このプロセスでは、ユーザーが意識してセキュリティモデルを変更する必要はありません。ソケットポリシーの例は次のとおりです。

<?xml version="1.0"?>
<cross-domain-policy>
   <allow-access-from domain="*" to-ports="1200-1220"/> 
</cross-domain-policy>"


このポリシーは事実上“任意のドメイン上のコンテンツは、ポート 1200 から 1220 間で自由にソケットを確立できる”と宣言しています。Unity の Webplayer はこれを尊重し、 その範囲外のポートを使用する場合はソケットの接続を拒否します( SecurityExceptoin がスローされます)。

UDP 接続を使用する場合のポリシーは、TCP と同様の方法で実施することができます。違いは TCP は自動でフェッチされる点です(サーバーへの接続を許可されてることを保証します)。この違いは、TCP は接続した際に自動でフェッチされますが UDP はフェッチされない点です。UDP はコネクションレスの際も API が参照されたときに送信もしくは受信を行います(送信及び受信を行うことを保証します)

ソケットポリシーに使用される形式は、いくつかのタグがサポートされていない事を除き、Flash Player と同じものです。Unity の webplayer は“*”のみをサポートしており、ドメインの設定と“to-ports”の設定が必須です。

<?xml version="1.0" encoding="ISO-8859-1"?>

<!ELEMENT cross-domain-policy (allow-access-from*)>

<!ELEMENT allow-access-from EMPTY>
<!ATTLIST allow-access-from domain CDATA #REQUIRED>
<!ATTLIST allow-access-from to-ports CDATA #REQUIRED>


UDP と TCP トラフィックの双方が接続できるポリシーサーバーは、TCP と UDP の接続の両方に有効です。

利便性のため、我々は 843 ポートで待機する小さなプログラムを提供し、それに接続した際にソケットポリシーに文字列を返信します。 サーバーのコードは、Unity がインストールされているフォルダーの、Windows であれば Data/Tools/SocketPolicyServer、OSX であれば/Unity.app/Contents/Tools/SocketPolicyServer で見つける事ができます。事前に構築された実行可能ファイルは Mac 上で動作可能なことに注意してください。“mono sockpol.exe”と入力すると動作します。このサンプルはソケットポリシーサーバー( socket policy server )の正しい振る舞いを表します。具体的にはサーバーが含まれている 0 ( 0 )で終わる文字列を受信することを想定し、<policy-file-request/> を含めます。この場合、クライアントはこの文字列を受信した際に socket policy.xml ドキュメントを送信します。さらに、xml ヘッダーと xml ボディも要求され、シングルソケットより送信します。送信中にヘッダーとボディをソケットの書込み中に壊すと、不完全なポリシーの受信によるセキュリティ例外を引き起こす可能性があります。もしサーバーでで問題が発生した場合、当社の提供するサンプルを用いて検討してください。これは問題がサーバーサイドかクライアントサイドか判断するのに役立ちます。

一般的に、マルチプレイヤーネットワーキングに使用されるサードパーティ製のネットワークライブラリは、それらが P2P 機能(下記参照)に依存しますが、専用サーバーを使用しない限りこれらの案件で動作することができるはずです。これらのときには、型はずれのホスティングポリシーをサポートする場合があります。

注意: crossdomain.xml とソケットポリシーファイルは両方とも xml ドキュメントで似ていますが、文章が提供されている方法は非常に異なっています。Crossdomain.xml ( HTTP リクエストに適応する)はポート 80 を利用して取り出され、ソケットポリシーがポート 843 を利用しているトライアルサーバーを経由し、&lt;policy-file-request/&gt; を実施しフェッチされます。ソケットポリシーファイルを発行するには、Http サーバーを使用する必要があり、また単純にポート 843 でソケットポリシーファイルを送信しソケットポリシーファイルを送信するサーバーをセットアップすることはできません。接続する各サーバーが独自のソケットポリシーサーバーを必要とする点にも注意してください。

デバッギング

ソケットポリシーサーバーは telnet を使用して接続することができます。セッションの例を以下に示します。

host$ telnet localhost 843
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
<policy-file-request/>
<?xml version='1.0'?>
<cross-domain-policy>
        <allow-access-from domain="*" to-ports="*" />
</cross-domain-policy>Connection closed by foreign host.
host$

この例のセッションではポート 843 から telnet で localhost に接続しています。Telnet 接続は最初の 3 行を使用して応答し、後はユーザーが入力するのを待っています。次にユーザーポリシー要求の文字列を <policy-file-request/> を送信すると、ソケットポリシーを応答し、その後サーバーは接続が閉じられた為に Telnet を切断しています。

リスニングソケット( Listening sockets )

あなたは Web Player でリスニングソケットを作成 できません し、それはサーバーとして機能させることもできません。したがって Web Player で相互に直接通信( P2P )することはできません。TCP ソケットを使用するときは、それがソケットポリシーシステムを通過することが許可され提供されるリモートエンドポイントにのみ接続することができます。UDP の場合も同様に動作しますが、それはコネクションレスのプロトコルとしてコンセプトが少し異なっているため、パケットを送受信するために Connect/Listen する必要がないためです。これは最初に allow-access-from domain タグが含まれている有効なポリシーを受信した場合のみ有効になります。

これはまったく迷惑な話です。なぜこのようなものが存在するのでしょうか?

ソケットや WWW のセキュリティ機能は、Unity Web Player をインストールした人を守るための機能です。これらの制限がない場合、下のようなストーリーが発生するかもしれません。

  • ボブはホワイトハウスで働いています。
  • 極悪人のフランクが居ます。フランクはホワイトハウスの http://internal.whitehouse.gov/LocationOfNuclearBombs.pdf (核爆弾の配置に関する資料)を狙っています。http://internal.whitehouse.gov は国家機密のためインターネット上からアクセスできませんが、ホワイトハウスで働くボブのワークステーションからならばアクセスできます。
  • このゲームがダウンロードした PDF は http://frank.com/secretDataUploader.php に送信されます。
  • フランクは http://www.frank.com/coolgame.unity3d にゲームを配置します。
  • フランクはボブを説得し、ボブはフランクの作ったゲームをプレイしてもらいます。
  • ボブがゲームをプレイしています。
  • ボブがプレイしている間にゲームはコッソリ国家機密をダウンロードし、フランクに送信します。

WWW と Socket はセキュリティを備えているためこの攻撃は失敗するでしょう。なぜなら、PDF をダウンロードする前に Unity は http://internal.whitehouse.gov/crossdomain.xml にサーバーに「そのデータの所有者は貴方で、公的に利用することができるか?」と訪ねるためです。この場合、通例では webserver の crossdomain.xml は応答で見ることができます。このケースでは internal.whitehouse.gov のシステムオペレーターが crossdomain.xml を配置していない場合、Unity は PDF のダウンロードや読込を行うことができません。

残念なことに、Unity Web Player をインストールする人々を守るため、Unity 開発者はこれらのセキュリティ対策を講じる必要があります。この制限は Flash や Silverlight、Shockwave にも同様に存在します。

例外

Web Player のユーザーを保護しつつコンテンツ開発を容易にするため、上記のメカニズムに例外を設けています。

もし crossdomain.xml がない場合でも、サーバーから画像のみダウンロードすることを許可しています。しかし、この画像を使用してできることはシーン上でテクスチャとして使用することです。それらに対し GetPixel() を使用することは許可されておらず、また画面から再度読み込むこともできません。このどちらかを行った際、Unity は SecurityException をスローします。

SecurityException: No read access to the texture data: 
  at (wrapper managed-to-native) UnityEngine.Texture2D:GetPixel (int,int)


この理由は、画像のダウンロードはコンテンツデベロッパーがアクセス権を許可するかぎり問題ありません。このためユーザーに表示することはできますが、画像のバイトを別のサーバーに送信することはできません。もしピクセルデータをアクセスする必要があれば、crossdomain.xml ファイルを画像のフェッチができる場所に配置してください。

Web Player のトラストチェーンを使用する
Web Player のトラブルシューティング