水無月ばけらのえび日記

bakera.jp > 水無月ばけらのえび日記 > 2007年のえび日記 > 2007年7月 > 2007年7月27日(金曜日)

2007年7月27日(金曜日)

マンガ買った

平日なのに大量購入。

「日常」はよく分かりませんが勢いで買ってしまったという。未読なのでアタリかハズレかは全く不明。

あと、Amazon 見て気がつきましたが、ドージンワーク4 って限定版 (www.amazon.co.jp)が存在するのですね。とりあえず表紙タイトルの色が違うようですが、他に何が違うのだろう……。

関連する話題: マンガ / 買い物 / 日常

RSSで任意のドメインに誘導されてしまう脆弱性

tDiaryの脆弱性に関する報告(2007-07-23) (www.tdiary.org)」……って、これ、えび日記のRSSが脆弱という話とまるっきり同じですね。RSSが変だと指摘されて……という流れまで全く同じです。

そういえば脆弱性の詳細を書くと言いつつ全く書いていなかったので、深く反省。改めて書いておきます。

えび日記の RSS の脆弱性について

この「えび日記」は RSS 1.0 のフィードを生成していますが、そのフィード中の URL のドメインを任意のものに変えられてしまうという脆弱性がありました。

RSS の中では絶対 URL が必要になりますが、Web アプリケーションが自身の「正しい」絶対 URL を知るのは意外に難しいのです。たとえば ASP.NET の場合、Request.Url の値を取ると現在の URL が分かるのですが、このとき、ドメインは単にリクエストの Host: フィールドの値になります。ですので、Request.Url の値をそのまま信用してしまうと、Host: の値がそのまま RSS に出力されることになります。

名前ベースのバーチャルドメインの場合、不正な Host: ではアクセスできなくなるので問題ありません。しかし、任意の Host: を受け入れるようになっている場合は注意が必要です。悪意あるユーザが、悪意あるサイトのドメインを Host: に入れてアクセスしてきた場合、Request.Url の値は悪意あるサイトのドメインになります。それをそのまま RSS に出力すると、悪意あるサイトの URL を含む RSS が生成されてしまうわけです。ただし、この RSS を受け取るのはアクセスしてきた本人だけ……と言いたいところなのですが、hatomaru.dll は内部的にデータをキャッシュしているので、キャッシュされたデータを他のユーザも受け取る事になってしまいます。

というわけで、具体的には以下のような手順で攻撃が成立します。

  • 悪意あるドメイン evil.example.com を用意する
  • Host: evil.example.com となるようなリクエストを行う。ツールでリクエストを出しても良いですが、Hosts を編集するのが簡単かも。

これだけです。キャッシュを更新するタイミングでこのリクエストが行われると、悪意ある URL を含む RSS が生成されて、キャッシュされます。hatomaru.dll の場合、キャッシュ生成のタイミングは「日記更新直後 or 掲示板書き込み直後」なので、掲示板に書き込んですぐにこのリクエストを出すとたいてい成功します。

以上のような状況でしたので、以下のように対応しました。

  • ひとまず一時的な対処として、名前ベースのバーチャルドメインを有効にして、Host: bakera.jp でないアクセスを弾くようにした。「HTTP/1.0 でアクセスできないかも」と言っていたのはこのためです (HTTP/1.0 では Host: が必須ではない)。
  • その後いろいろ改造して、絶対 URL 生成時には設定ファイルから読み取った文字列をドメインとして使用するようにした。ちなみに本番環境の設定ファイルには bakera.jp という値が、テスト環境には localhost という値が設定されているので、うっかりテスト環境のファイルをそのまま本番に持っていくとおかしな事になります (なりました……)。

とまあ、こんな感じです。tDiary の場合、設定で後者のような挙動になるようなので、単にその設定を使用すれば良さそうですね。

関連する話題: セキュリティ / hatomaru.dll

HttpHandler で Bad Request の謎

アマ検」を作ってみたのですが、いろいろ検索してみると、「"」や「<」を含む文字列を検索すると死亡するという問題がありました。どうも HttpHandler を使っている場合、パスに特定の文字列が含まれていると例外が出たり、Bad Request と言われて怒られたりするようです。

ただし、クエリの場合はそれらの文字が含まれていても平気です。「http://bakera.jp/amazon/books/%22」はダメですが、「http://bakera.jp/amazon/books?%22」だと OK なのです。考えてみれば、「"」や「<」は、Windows のファイルシステムでパス名に使用できない文字ですから、HttpHandler はどこかでパスをファイル名にマッピングしようとしていて、ファイル名に使えない文字に当たると死んでしまうのかもしれません。

そこで、検索文字列にパス名として使えない文字が含まれている場合には、それがパスの一部ではなくクエリ文字列として渡るように改造しました。これで、「"」や「<」が含まれる文字列も検索できるようになりました。

※ちなみに、「パス名に使えない文字」は System.IO.Path.GetInvalidPathChar() で取得しています。

これで解決……と、思いきや。いろいろ試してみると、何故か「&」や「%」でも死亡するのでした。これらはパス名に使える文字なので、単純に「パス名として不正だから死ぬ」という訳でもないようですね。

※追記: なんかいろいろ駄目なので元に戻しました。orz アマ検は停止中です。

関連する話題: ASP.NET / C# / hatomaru.dll / 失敗談

最近の日記

関わった本など