ここが危ない!Web2.0のセキュリティ

第2回Same-Originポリシーと迂回技術

Same-Originポリシー

第2回はAjaxに関するセキュリティモデルを紹介します。第1回で紹介した、Ajaxを用いてリクエストを送信するコードをもう一度見てみましょう。

Ajaxを使い通信を行う部分は次のように記述しました。

req.open('GET', 'http://www.example.com/contents.txt');

このURLの部分を、HTMLファイルが置かれているサーバとは別のドメインのURLに書き換えてみます。するとリクエストは送信されなくなったと思います。

これはセキュリティ上の理由から、他のドメインのサイトへはリクエストを送信できないように制限がかけられているためです。この制限のことをSame-Originポリシーと呼びます(他にもSame-Originルール、クロスドメインセキュリティモデルとも呼ばれます⁠⁠。一方、他のサイトへアクセスすることをクロスドメインアクセスと呼びます。

図1 Same-Originポリシー
図1 Same-Originポリシー

Same-Originポリシーの必要性

それではなぜSame-Originポリシーが必要なのかを理解するために、もしSame-Originポリシーを破ってクロスドメインアクセスが行われた場合にどのようなことが起こるかを考えてみます。

ユーザはWebメールを提供しているサイトにログインし、メールを読んでいるとします。

図2 クロスドメインアクセス
図2 クロスドメインアクセス

ユーザはメールを読んでいる最中に用事を思い出し、www.securesky-tech.comにアクセスしに行きました。…(1)

このときwww.securesky-tech.comのサイトにリスト1のようなスクリプトが書かれていたとします。…(2)

リスト1 
<script language="javascript">
  var req;
  if( window.XMLHttpRequest){
    req = new XMLHttpRequest();
  }else if(window.ActiveXObject){
    try {
      req = new ActiveXObject("MSXML2.XMLHTTP");
    } catch (e) {
      req = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  if (req) {
    req.open('GET', 'http://mail.example.com/mail/index.html'); // (3)クロスドメインアクセス
    req.onreadystatechange = function() {
      if (req.readyState == 4) {
        sendtoAttacker(req.responseText); // (4)取得した情報を攻撃者のサーバへ送信
      }
    }
    req.send(null);
  }
</script>

するとWebメールのサイトにリクエストが送信されます。…(3)

その結果、レスポンスとしてWebメールにログイン後の画面を取得することができます。なぜなら、認証情報を格納しているCookieというデータは、Webメールのサイトにアクセスするたびにブラウザが自動的に送信する仕組みになっているためです。

その後、取得した画面の内容が攻撃者のサイトに送られます。…(4)

このように、もしSame-Originポリシーが存在していなければ、個人情報が盗まれ放題になってしまいます。

実際にはクロスドメインアクセスは禁止されていますので、上記で説明したようなことは起こりません。www.securesky-tech.comとmail.example.comはドメインが異なるので、アクセスできないようになっています。

なお、同じドメインであってもポート番号やプロトコル(HTTPとHTTPSなど)が異なれば、異なるサイトとみなされアクセスできません。また、Same-OriginポリシーはAjax(XMLHttpRequestオブジェクトを使用した通信)にだけ存在するわけではなく、スクリプトを用いてフレームやサブウインドウの情報にアクセスする場合などにも存在しており、Webの世界での基本的なルールとなっています。

Same-Originポリシーの迂回

とはいっても、いろいろとサービスを提供するためには、クロスドメインでアクセスできたほうが便利なことがあります。

ドメインの異なる2つのサーバを管理しており、これらの間で互いにデータをやりとりしたい場合や、APIを提供しているサービスからデータを取得したい場合などが考えられます。とくにWeb2.0では、他者が提供しているサービスを利用してサイトを構築することが多いため、クロスドメインでアクセスしたいという要望は高くなります。

このような場合にクロスドメインアクセスを実現する方法として、以下のものがあります。

  • リバースPorxy
  • SCRIPTタグ(JSONP)
  • Flash
  • 画像
  • スタイルシート

この中でリバースProxy、JSONP、Flashを使う方法がよく使われます。それぞれの方法についてセキュリティという視点を含めて見ていきたいと思います。

リバースProxyを使う方法

Proxyサーバを設置し、Proxyサーバにデータ提供サーバのデータを取りに行かせる方法です。

ユーザのブラウザからは1つのサーバにアクセスしていますが、そのサーバが裏でデータ提供サーバにデータを取りに行くことになります。

図3 リバースProxy
図3 リバースProxy

さて、この場合のセキュリティについて考えてみます。

不特定多数の人がこのProxyサーバにアクセスできるようになっていると、不正アクセスの踏み台として利用される可能性があります。

データ提供サーバから見ると、すべてProxyサーバからのアクセスにしか見えないため、攻撃者は自分の身元を隠してデータ提供サーバへアクセスすることができます。攻撃者から見ると、攻撃を行う際の隠れ蓑として利用できるのです。

また別の問題として、データ提供サーバで認証が必要とされている場合、ユーザは認証情報をProxyサーバに渡さなければなりません。この場合、Proxyサーバではデータ提供サーバの認証情報をユーザから受け取るため「本来の用途以外には使用しません」と但し書きをすることになるでしょう。しかしたとえ但し書きがされていたとしても、入力を躊躇するユーザもいると思います。また、Proxyサーバ側としても余計な疑いをかけられたくないため、できれば個人情報は持ちたくないところです。

リバースProxyを使う場合のセキュリティ対策

では対策について考えてみましょう。以下の3つが挙げられます。

接続先のサーバを制限する
Proxyサーバが情報を取りに行くサーバを限定します。たいていのサービスでは任意のサーバに情報を取得しにいく必要はないと思います。制限することによって攻撃者からみると利用価値の限られたProxyサーバになりますので悪用される可能性も低くなります。
認証を行う
Proxyサーバを利用できるユーザを限定します。しかし、不特定多数のユーザに提供しているサービスではこの方法を使うことはできません。
認証情報を扱わない
残念ながらProxyサーバ側で認証情報を扱わないで認証を行うことはできません。サーバ側で認証情報を扱わないで認証情報を必要とするサービスを利用する方法は次回以降で紹介したいと思います。

Same-Originポリシーを迂回するという覚悟

クロスドメインアクセスを許可するようなサービスを提供するということは、セキュリティ的に保護されている部分を自ら破るということです。クロスドメインアクセスは機能として実装されていないのではなく、セキュリティ上の理由から禁止されているということを認識しておいてください。

それでもサービスを提供する場合には、冒頭で述べたような被害が発生しうることを想定しておく必要があります。

今回は、リバースProxyを使ってSame-Originポリシーを迂回する方法を紹介しました。JSONPとFlashを使う方法については、次回以降で紹介したいと思います。

おすすめ記事

記事・ニュース一覧