Ajaxとセキュリティ

「PHPカンファレンス2006」でAjaxについて話題になっていたのだけど、「こんなことできるようになるよ。」という話が主で「セキュリティ的にどうなの?」と言う話は脇役だったのですが、どちらかというとそっちの方が気になった。

ちょっとだらだらと書いてみる。

■WebServerの役割の違い

WebServerはBrowserからのGET,POSTに対して何らかの返信をするという意味においてはAjax以前も以後も変わらない。

Ajax以前は、WebServerは「HTMLを返す」という仕事ですよね。

 . WebServer               Browser
.  |                        |
.  |< ----------------------|GET,POST
.  |---------------------- >|HTMLとして表示 

Ajaxでは、WebServerは「データ(XML,JSONなど)を返す」という仕事に変わってくる。

 . WebServer               Browser
.  |                        |
.  |< ----------------------|GET,POST
.  |---------------------- >|Jsで加工して表示 

まとめ。
・「HTTPプロトコルを使う」と言う意味ではAjax以前後でかわりはない。
・「どういうデータを流すか?」が違ってくる。

■Ajax以前は同期、Ajaxは非同期

Ajax以前は「GET、POSTで1画面まるまる表示切り替え」であったけど、 Ajaxでは「1画面は、複数のGET,POSTにより構成される。しかもGET,POST は非同期に行われる」である。

■通信データの*中身*の変化

Ajax以前は、
そもそも「1画面」という処理単位であるから、サーバからもらった 「1画面分のデータ=HTML」をそのまま表示すればよかった。

Ajaxでは「データの中身は決まっていない」
# というか「データの中身の意味づけは自由にしてくれ」とか
# 「WebServerがデータを返したところで、どうせBrowserで処理するのだから、
# Browserで処理しやすいような形式のデータを返せばよい」
# とかそういう感じ。

従って、Ajaxでは「個々の通信データに*意識して*意味を持たせること」が必要になった。
ようは、Ajaxでは「WebServerとBrowser間のAPI設計」が必要になった。

■APIが丸裸

APIといっても、AjaxのAPIは丸裸度が高い

まず『データの中身を覗き見しやすい』
Browser(Javascript)で処理することを前提にしたデータを流すので、 Ajaxでやり取りされるデータは結局のところ
・HTML
・JSON
・XML
・CSV
になってくる。
何れもテキスト形式(≠バイナリ)だから、通信パケットを覗けば 人間にとっても判読しやすいデータ形式である。

次に『Browser上のソースコード(Javascript)も覗き見しやすい』
ソースコードもテキスト形式だから用意に解析できる。APIを独自に組み合わせて 「公式Ajaxクライアント」ではなく「俺様Ajaxクライアント」なるものを 作りやすい。

また、従来の『1画面のデータをまるごとHTML』という大雑把なものではなく Ajaxは『設計されたデータ=構造化されたデータ』が流れているから、 「意味のある情報を機械的に判別しやすい」という事情もあるから 「俺様Ajaxクライアント」が存分に「俺様ぶり」を発揮する可能性が高い。

もっとも「俺様Ajaxクライアント」を実際に動かすことができるかは、 さらにいくつかハードルを越えないといけないけど。

■「俺様Ajaxクライアント」を実際に動かせるか?(1)

まず、Ajaxでは非同期なGET,POSTを実現するのに XMLHttpRequestなるものを使う。 (使わなくてもAjaxできるのだけど、XMLHttpRequest使う方が 楽できるから、こちらの方が圧倒的に多い)

XMLHttpRequestには『クロスドメイン制限』という*制限*が あります。

 . Server1                   Client
.  |                          |
.  |< ---------------------- >|(1)GETでJSソース取得
.  |                          |
.  |< ---------------------- >|(2)XMLHttpRequest
.  |                          | 

この制限の為、
Server1から取得したJSを実行している限り、 XMLHttpRequestでアクセスできるのは、Server1だけであって その他のServer2とかにはアクセスできないわけですね。
# (1)と同じホストに対してしか(2)はできない。

つまり、「俺様Ajaxクライアント」を作ったとしても Server1上に「俺様Ajaxクライアント」を置いてもらわないと、 動かないということです。

つまり、 *Server1の脆弱性を突いて「俺様Ajaxクライアント」をServer1に 忍ばせることができれば*、第三者に「俺様Ajaxクライアント」を 踏ませることができる。
ということですね。

■「俺様Ajaxクライアント」を実際に動かせるか?(2)

XMLHttpRequestには『クロスドメイン制限』ですが、 以下のような方法でかいくぐることもできます。

 . Server1       ServerX     Client
.  |              |           |
.  |              |< ------- >|(1)GETでJSソース取得
.  |              |           |
.  |< ---------- >|< ------- >|(2)XMLHttpRequest
.  |                          | 

「俺様Ajaxクライアント」とXMLHttpRequest中継Cgiを ServerX上に配置すれば、Server1に「俺様Ajaxクライアント」で アクセスできます。

もっとも「そういうことも可能」というだけの話で、
・俺様サーバ(ServerX)を用意して、
・そこにXMLHttpRequest中継Cgiを配置して、
・第三者が、俺様サーバ(ServerX)にアクセスしてくれる。
これらを満たして、やっと第三者に対しての「俺様Ajaxクライアント」配布 ができる。

そもそも、第三者が俺様サーバにアクセスしてくれるのか?という話 もありますが、フィッシングの被害があるところを見ると、案外できてしまいそうです。

■「俺様Ajaxクライアント」を実際に動かせるか?(3)

とは言っても、XMLHttpRequestを使わなくても iframeを使ってAjax(非同期通信)を実現できるそうです。
それを使えば、

 . Server1       Client
.  |              |
.  |              |(1)直接クライアントのJSを実行
.  |< ---------- >|(2)iframeを使ってAjax 

ということができてしまうので、これを行われると どうしようもないですね。

■「俺様Ajaxクライアント」を実際に動かせるか?(4)

といいますか、

結局のところ、Ajaxと言えどHTTPプロトコルに従って いるのですから、JSとか関係なく、ガシガシと直接データ を流し込んでやれば何でもありなんですけど。

裏を返せば、Webアプリ全部に言えることですから、 Ajaxうんぬんという話ではなくなりますが。

■結局Ajaxのセキュリティリスクは?

感覚的には、
・API丸裸なところとか「怖いなぁ」と感じる。
・結局のところは、HTTPプロトコルに従ってるのだから今までとさほど変わらない。

論理的には説明できないんですけど、多分以下のような感じと解釈。
・Ajax以前も以後も防御する方法は同じ
・しかしながら、実際にはAjaxの方が複雑なので防御する難易度(?)としてはあがる。
# 複雑なことを、完璧に行うのは難しい
・一度、セキュリティホールが突かれてしまうと、被害が大きいのはAjax
# APIという仕組みが裏目にでそう

■追記

参考にさせて頂きました。

Ajaxの特徴に潜むリスクをサンプルアプリで確認しよう
http://www.atmarkit.co.jp/fwcr/special/ajax_kaitai02/02.html

を読むと「Ajax怖いなぁ」と思うのですが、

エースプログラマの uki-uki 日記
この記事の内容じゃあ、タイトルがただの「釣り」と思われちゃいますよ @IT さん
http://blog.g-up.com/hidenori_goto/?s=2&b=10587

「Ajaxのリスク」と「IEではクリップボードの内容をJavascriptで取得できる」
という話がごっちゃになってるよという話、なるほどーなのですが、

実際に

せつないぶろぐ : Ajaxに潜むリスクを再確認(クリップボード編):
http://f56.aaa.livedoor.jp/~tdnr/ppblog/index.php?id=06070009

のサンプルを実行すると「おぉ~」と思ってしまうのであって、 見せつけられるとタイトルから「Ajaxやっぱり恐いなぁ」なんて思ってしまうけど、 これはAjaxのリスクではない。Ajax使わなくても、クリップボードの中身盗めるから。

あなたのクリップボードが盗まれる - Ceekz Logs:
http://private.ceek.jp/archives/001639.html

ということですね。

Comments are closed.