snippets from shinichitomita’s journal RSSフィード Twitter

2007-01-05

[] クロスドメインでのデータ読み込みを防止するJavaScript ?

GMailのコンタクトリスト漏洩のエントリのついでに。

JSONデータをscriptタグにのせて配信するサービス(JSONPなど)で、限られたサイトのみにしかそのデータを配信しないようにするためには、クライアントが送出してくるリファラ情報を使ってサービスコンシューマとなっているサイトを特定してアクセス制御する方法がある。

この方法はおそらく大部分のクライアント(ブラウザ)に対しては有効で、例えば実際にGoogle MapsなどもそれとAppKeyを組み合わせてサイトを判別しているっぽいのだけど、意図的にリファラ送出を切っているブラウザであったり、あるいはプロキシプログラムなどが自動的にリファラヘッダを除去してしまうようなクライアント環境に対しては無効になってしまう。

ということで、そんなクライアントでもなんとかならないだろうかと考えていたときにちょっと思いついた、もしかしたらこの方法なら許可されていないサイトからのデータ読み込み(というより「利用」)を防ぐことが出来るかも?(ただしugly hack)

scriptタグ読み込みで送られてくるJavaScriptがこんな形になっているとする

callback(
  window.location.hostname=='www.example.com' ? 
  { /* JSON data is here */ } : 
  { error : 'Request not allowed from your site!' } 
)

これならwww.example.comにscriptタグを呼び出したHTMLが置いてない限り{ /* JSON data is here */ }の部分のJSONデータはアクセスできないよね? つまりJSONデータの「読み込み」はできても、外部の他のスクリプトから「利用」はできないということになる。

何か穴あるかな?方法が方法なんで、別にあってもおかしくはないけど、まだ見つからない。


ちなみに最初考えついたのは、

callback(
  window.location.href.indexOf('http://www.example.com')==0 ?
  { /* JSON data is here */ } : 
  { error : 'Request not allowed from your site!' } 
)

だったけど、これは呼び出す元のHTMLであらかじめ

String.prototype.indexOf = function() {  return 0 }

みたいなのを作ってしまえば回避できてしまう。

ということで上記のような形になりました。


JavaScriptは演算子オーバロード出来なかったよね?確か。

malamala 2007/01/05 23:16 思いつかないですね。__defineGetter__なんか怪しいかな、と思って試してみましたが失敗しました。

malamala 2007/01/05 23:23 文字コード指定をわざと変える、マルチバイト文字が化ける、スクリプトエラーが起きる、window.onerrorで補足する、で、エラー行のデータを読めるかも。思いつきですが。

llameradallamerada 2007/01/06 02:41 window.location.hostnameの上書きでは駄目なんでしょうか?

lameradalamerada 2007/01/06 02:44 上書きできませんね。失礼しました。

nanto_vinanto_vi 2007/01/06 16:45 IE/Operaだと以下ですり抜けられませんか?
var window = { location: { hostname: ”www.example.com” } };

malamala 2007/01/06 22:07 あー、そうやって代入するとページ移動しないですり抜けられますね。documentオブジェクトを確実に取れればdocument.domainなんかは制約かかってるようなので、使えそうな気がするのですが。

kazuhookukazuhooku 2007/01/06 23:03 callback(
(function () { return this.location.hostname; }).call() == ’www.example.com’ ?
...

だと大丈夫じゃないでしょうか?

nanto_vinanto_vi 2007/01/07 00:04 IE/Operaだとvar location = { hostname: ’www.example.com’ };でそれもすり抜けられるようです。

shinichitomitashinichitomita 2007/01/07 15:48 コメントいただいた情報によると、ブラウザ依存でも抜け道がありそうですね。まあいずれにせよみなさんの好奇心を刺激できたようで、エントリにあげておいてよかったかな^^;

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証