ガジェットのAPI
Windowsサイドバーガジェット用に用意されている拡張APIについて,このようなものがあるというのを簡単に紹介していきます。詳しくはWindows SDKまたはMSDN Online Libraryを参照してください。
スキーム
- gImage スキーム
gImageスキームはhttpやfileスキームと同じように指定して,ファイルのサムネイルや画像をリサイズした上で読み込むためのスキームです。
例えば,ファイルのサムネイルを得る場合に利用できます。使い方は以下のような感じです。
<img src="foobar.png" /> <!-- 通常通り --> <img src="gImage:///foobar.png" /> <img src="gImage:///foobar.png?width=100&height=100" />
オブジェクト
- System.Environment (環境)
環境変数の取得のためのメソッド,コンピュータの名前を取得するプロパティが提供されています。
- System.Gadget.SideShow (Windows SideShow)
Windows SideShow用のAPIを持っています。SlideShowではありません。SideShowとはノートコンピュータの液晶裏についたサブディスプレイなど情報補助表示装置です。その補助表示を操作するためのAPIが用意されています。
- System.ContactManager (アドレス帳)
メールなどのアドレス帳の内容を持っています。
- System.Machine (コンピュータ情報)
コンピュータそのものの情報,例えば,電源やCPU使用率,メモリ使用率などをもつオブジェクトをSystem.Machine.*に持っています。
- System.MessageStore (メール)
メールボックスの状態などを得ることができるオブジェクトです。未読件数などを表示するのに利用できます。
- System.Network.Wireless (無線LAN)
その名のとおり無線LANの接続状況についての情報を持っています。
- System.Shell (ファイル・シェル操作)
ファイル操作を助けるためのAPIを持っています。例えば,ファイルの移動やドラッグアンドドロップで渡された情報からファイル情報を簡単に得るための仕組みなどを提供してくれます。
- System.Sound (音をならす)
簡易的に音を鳴らすためのAPIを提供します。音楽を鳴らすというよりは効果音を鳴らすだけという用途向きです。もし音楽再生を求めているのであればWindows Media Playerを使うなどしてください。
- System.Time (時刻)
現在の時刻とタイムゾーンの管理を行うオブジェクトです。
セキュリティ的に気をつける点
ガジェットはマイコンピュータゾーンかそれ以上に危険であると思うべき
つまりユーザに特に訪ねることなく,コンピュータに対して様々なことを事実上無制限に行えます。これは常に念頭に置いてください。
また,Internet Explorerのマイコンピュータゾーンの設定によらずActiveXの実行などが許可されるため,Internet Explorerよりも危険な状態にあるといえます。
不用意にevalしない
evalというのは知っての通り任意のJavaScriptを評価する関数です。
evalを使う場面はJSONを使う場合(以前のサンプルもそうでした)に多く見られると思いますが,もし出力形式にXMLやその他形式を選択できるのであれば避けることをお勧めします。
そもそもevalを利用して外部から得たスクリプトの文字列を評価するというのは,その得られた文字列が安全であるということを証明できない限り避けるべきです。
なぜならば先ほども述べたとおり,ガジェットはマイコンピュータゾーン相当で動作しているからです。つまり,悪意あるスクリプトを受け取りevalしてしまった場合やりたい放題になってしまいます。それこそ,ファイル操作やXMLHttpRequest,ActiveXObjectでCOM操作も何でも,です。
では,「文字列が安全であるかどうかを証明できるのか」というと,これもまた面倒な話です。悪意あるスクリプトが返される理由は経路上での改ざんやそもそも悪意あるサービスだった場合などがあげられますし,自分の信頼できるサーバでSSLを使ったとしても,そもそもサーバのデータが改ざんされていないことを証明しなければいけません。ということは電子署名のようなことを行えば何とかできそうです。という感じで一筋縄ではいかないのです。
もっともevalを必要とする場面というのは,いいところJSONをデシリアライズする点ぐらいしか考えられないので,JSONをやめることができないかどうかを考慮した方がよいでしょう。
エスケープのし忘れに気をつける
いわゆるXSS(クロスサイトスクリプティング)を防ぐという話です。
悪意ある入力を引き継いでガジェットを動作させることは一般的なWebアプリケーションよりは困難ですがあり得ないわけではないですし,外部から取得したHTMLが悪意あるものである可能性もあります。そのようなものを何も考えずinnerHTMLプロパティにセットするとeval同様大変なことが起こる可能性があります。
そもそもそういうセキュリティ面もそうですが,正しく表示できていない時点で不具合ですから受け取った表示するときにはHTMLをきちんとエスケープします。
また,HTMLをエスケープするよりもinnerTextプロパティを使うことができるかどうかを検討するのもよいと思います。innerTextプロパティはinnerHTMLプロパティと似たもので「要素の内容テキスト」を表すプロパティです。このプロパティはあくまで表示するテキストなのでエスケープしない状態でセットできるのです。下手にエスケープするより単純で間違いがありません(もちろんinnerHTMLとinnerTextを間違えたら悲惨ですが……)。
var html = "<p><!-foo -->bargao </p>";
element.innerText = html; // <p><!-foo -->bargao </p>
element.innerHTML = html; // bargao

