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
ということですね。