Ajaxの特徴に潜むリスクをサンプルアプリで確認しようAjax解体新書(2)(3/4 ページ)

» 2006年07月19日 00時00分 公開
[木村利幸株式会社NTTデータ]

マウス座標位置のトラッキング

 次に、ユーザー操作監視の事例について見ていきたいと思います。典型例としては、ユーザーのキー操作をすべて記録してしまう「キーロガー」があります。この動作は、極めて単純で、最も有名なAjaxアプリケーションの1つである「Google Suggest」をイメージしていただければ、理解が早いと思います(ここでは、キーロガーの動作原理を理解しやすくするために例示しているだけで、決してGoogle Suggestがキーロガーであるという意味ではありません)。

 ユーザーが、何らかの文字を入力するたびに新しい検索キーワードで検索し、その結果をリアルタイムに画面に反映させるという、非常に効果的なアプリケーションです。ただ、この技術を悪用すれば、ユーザーにデータ転送を意識させない形で、キー操作をすべて記録することも可能となってしまいます。このようなアプリケーションは、Ajaxベースのキーロガーともいうべき機能を提供することになります。

 ただ、前述の「クリップボード参照」の影響範囲がWebブラウザを超えたWindowsデスクトップ全体であったのと比較すると、このキーロガーは、Webブラウザ内のキーイベントしか取得できないため、限定的となります。とはいっても、サーバへ転送されるとは考えていない情報も含めて送信されてしまうリスクは意識しておく必要はあるでしょう。

 今回は、インターネット上に比較的情報が多いキーロガーではなく、マウスの座標位置をトラッキング(逐次取得)して、サーバへ転送する事例を紹介したいと思います。より理解を深めるため、Microsoft社のWebブラウザであるIEで実際に動作するサンプルを用いて解説します。

 対象となるアプリケーションは、図5のような画面を持っており、画面上の「A領域」と「B領域」のいずれかの上にマウスカーソルを移動させると背景色が変化し、選択状態となるというものです。この画面を実現するHTMLソースは、リスト2の「mousetrace.htmlソース」です。まず、このアプリケーションを開始させるためには、「実行」ボタンを押します。すると、「残り10秒」からカウントダウンがスタートし、それがゼロになるまでエリア内でマウスカーソルを自由に移動させることができます。

図5 マウストラッカー画面(クリックしてFlash表示) 図5 マウストラッカー画面(クリックしてFlash表示)
<html>
<head>
 <title>マウスとレース</title>
 <link rel="stylesheet" href="http://sample.atmarkit.jp/fux/0607/19/mousetrace.css" type="text/css">
 <script language="JavaScript" src="http://sample.atmarkit.jp/fux/0607/19/mousetrace.js"></script>
</head>
<body>
<!-- コマンド表示エリア -->
<div id="iC" class="command">
 <input type="button" value="実行" onclick="init();">
 <input type="button" value="再生" onclick="play();">
 <input type="button" value="隠しデータ表示/非表示"
  onclick="showAndHide();">
</div>
<!-- マウストラッキングエリア -->
<div id="iT" class="trackingArea">
 AかBをマウス選択: 残り<span id="iR" style="color:red">0</span>秒
 <!-- 選択エリア「A」 -->
 <div id="iA" class="choiceA"
 onMouseOver="changeColor('iA','#ffff00')"
 onMouseOut ="changeColor('iA','#aaaaff')">A</div>
 <!-- 選択エリア「B」 -->
 <div id="iB" class="choiceB"
  onMouseOver="changeColor('iB','#ffff00')"
  onMouseOut ="changeColor('iB','#aaaaff')">B</div>
</div>
<!-- マウス位置履歴の格納エリア(表示/非表示切り替え可) -->
<textarea id="iL" class="logArea" rows="4" cols="40"></textarea>
<!-- マウス位置再現用のポインタ(再生時のみ表示) -->
<div id="dot" class="dotStyle"></div>
</body>
リスト2 mousetrace.htmlソース

マウスの動きを記録する

 このサンプルアプリケーションには、「ユーザーのマウス操作に合わせて背景色を変化させる」という通常の機能のほかに、「後から過去のマウス移動を忠実に再現する」という隠された特別な機能があります。画面上の「再生」ボタンを押すと、図6のように赤いカーソルが表示され、過去のマウス操作をなぞるように自動的に移動します。

図6 マウス移動の再生画面(クリックしてFlash表示) 図6 マウス移動の再生画面(クリックしてFlash表示)

 では、この機能をどのようにして実現しているのかについて解説します。この動作を理解しやすくするため、「隠しデータ表示/非表示」ボタンが用意されています。このボタンを押すと、リスト3にあるshowAndHide()関数が呼び出されることによって、図7のようにいままで表示されていなかったテキストエリアが表示され、その中に何らかのデータが格納されていることが分かります。

function showAndHide() {
 // ログ領域スタイル情報の取得
 var target = document.getElementById("iL").style;
 // トグル表示: 「表示」<-> 「非表示」切り替え
 target.visibility = (target.visibility=='visible') ?
            'hidden' : 'visible';
}
リスト3 mousetrace.jsの表示切り替え関数「showAndHide()」

図7 マウス位置履歴の表示画面(クリックしてFlash表示) 図7 マウス位置履歴の表示画面(クリックしてFlash表示)

 このデータを拡大表示したものが、リスト4のマウス位置履歴データです。数値とカンマ(,)およびセミコロン(;)で構成されており、ある時点でのマウス座標が「X座標,Y座標;」という形で表現されています。このデータを取得しているのは、リスト5のマウス位置取得関数「tracker()」です。この関数は、100ミリ秒ごとに呼び出され、その時点でのマウス座標が特定の領域内であった場合に、ログ領域に追加保存する形になっています。

76,15;76,23;83,75;83,75;83,79;82,85;82,
85;79,86;76,85;75,93;75,108;183,104;187
,
95;180,87;170,82;153,82;141,82;126,82;
111,82;98,82;86,82;83,86;86,97;92,107;2
04,107;211,91;213,89;213,89;213,89;215,
88;267,79;287,79;287,79;309,82;3
21,89;321,,89;326,99;329,109;222,109;21
7,101;219,95;229,,91;229,91;230,91;238,
99;283,100;283,100;283,100;288,100;28
0,101;245,104;188,101;149,100;149,100;
149,100;149,100;148,100;165,103;165,1
03;193,105;193,105;215,105;235,106;24
4,105;252,105;252,105;255,105;239,10
5;216,103;
リスト4 マウス位置履歴データ

function tracker(){
 if(document.all){
   // ログ領域の取得
   var out = document.getElementById("iL");
   // 現マウス座標(cx,cy)が取得領域内(sx,sy)-(lx,ly)かどうか
   if ((cx>sx)&&(cx<lx)&&(cy>sy)&&(cy<ly)) {
    // ログ領域に「X座標,Y座標;」の形式で追加
   out.value += cx+","+cy+";";
   }
 }
 // 記録モードの場合、100msごとにマウス位置記録
 if (tracking) setTimeout('tracker()',100);
}
リスト5 mousetrace.jsのマウス位置取得関数「tracker()」

 再生の仕組みは、図8において「再生」ボタンを押すと、リスト6に示されるplay()関数が呼び出されます。この関数は、リスト4にあるようなマウス位置履歴情報を読み込み、記録時と同じ100ミリ秒単位でリスト7に示す描画関数plot()を呼び出します。このプログラムによって、ユーザーのマウス操作が後から再生できてしまうことが分かります。

図8 画面をクリックすると、mousetraceプログラムで実行、記録、再生が確認できる(Windows版IEバージョン6でのみ動作確認を実施) 図8 画面をクリックすると、mousetraceプログラムで実行、記録、再生が確認できる(Windows版IEバージョン6でのみ動作確認を実施)

 ここで最も注目すべき点は、マウスの操作履歴を取得されているのかどうか通常ユーザーは一切気付かない可能性が高いという点です。さらに、今回のサンプルではすべてローカルで処理していますが、Ajaxとの組み合わせによってユーザーに知られずに、これらの取得データをサーバに転送してしまうことも可能となる点を意識しておく必要があるでしょう。

function play() {
 // ログ領域に記録されたマウス位置履歴情報を取得
 var log = document.getElementById("iL").innerHTML;
 // 「;」を区切り記号として配列(positions)に格納
 positions = log.split(";");
 // データの最終データを無効化するため、配列から削除
 positions.pop();
 // 再生用カーソルを表示
 document.getElementById("dot").style.visibility="visible";
 // 100ms単位で、描画関数(plot)を呼び出す
 th = setInterval('plot()',100);
}
リスト6 mousetrace.jsのマウス位置取得関数「play()」

function plot() {
 // X座標とY座標を対で格納する配列を宣言
 var position = new Array();
   
 // 履歴データ数より描画済みデータが少ない場合
 if (plotted < positions.length) {
   // 履歴データ数より描画済みデータが少ない場合
   position = positions[plotted].split(",");
   // X座標とY座標をセットし、描画済みデータ数をインクリメント
   document.all("dot").style.left = position[0];
   document.all("dot").style.top = position[1];
   plotted++;
 } else {
   // 描画済みデータ数を初期化
   plotted=0;
   // タイマを停止させ、再生用カーソルを非表示
   clearTimeout(th);
   document.getElementById("dot").style.visibility="hidden";
 }
}
リスト7 mousetrace.jsのマウス位置取得関数「plot()」

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。