Top | Software | Wiki | Ruby | Tama | Diary

Wikiもどき セキュリティ情報

このページではWikiもどきのセキュリティに関する情報をお知らせします。ご不明な点がありましたら岩月までご連絡ください。

差分表示処理中においてDoS状態に陥る脆弱性 (2006-07-03)

20050205.2版までのWikiもどきに含まれる差分表示機能におきましてDoS状態に陥る脆弱性がありました。

Wikiもどきの差分表示機能とは、異なる二つの版のページの内容を比較し、二つの版の差分を表示するものです。その二つの版の差分が多数に及ぶ場合、差分情報の作成に大量のCPU時間を長時間必要となり、その為Wikiもどきが動作しているマシンに対してDoS状態を引き起こす可能性があります。

ここではその脆弱性の対処方法をお知らせいたします。

なおこの脆弱性は、産業技術総合研究所 田中哲氏によりIPAへ報告されました。それによりJPCERT/CCを通じて岩月へ報告をいただきました。発見者並びにご協力いただいた方々に感謝いたします。

対象となるバージョン

Wikiもどき 20050205.2版より以前の全て。

対処方法

二通りありますが、前者の方法(機能の無効化)は根本的な対処方法ではありませんので、後者の方法(時間制限を設ける)をお勧めいたします。

対処方法A (差分表示機能を無効にする)

wikimodoki-config.rbでdiff.rbを無効にします。具体的な方法は PLUGIN_LIST への設定内容により変わります。

プラグインリストに * がある場合は -diff.rb を書き加えます。

PLUGIN_LIST = '*'          # 対処前
PLUGIN_LIST = '* -diff.rb' # 対処後

また、単に diff.rb が書かれている場合には diff.rb を取り除きます。

PLUGIN_LIST = 'all.rb recent.rb diff.rb'  # 対処前
PLUGIN_LIST = 'all.rb recent.rb'          # 対処後

対処方法B (差分表示機能の処理に時間制限を設ける)

Wikiもどきのソースファイル(plugins/diff.erb)に対して以下の差分で示すような変更を施します。この差分では、差分情報の作成処理に3秒以上かかった場合にその処理を中断します。

--- diff.erb	22  5 2006 03:19:12 +0900	1.10
+++ diff.erb	02  7 2006 17:52:46 +0900	
@@ -34,7 +34,14 @@ end
 </div>
 
 <%
-diffs = Wiki::Diffs.textdiff(self[rev1 - 1].src, self[rev2 - 1].src)
+require 'timeout'
+diffs = (begin
+           timeout(3) do
+             Wiki::Diffs.textdiff(self[rev1 - 1].src, self[rev2 - 1].src)
+           end
+         rescue TimeoutError
+           [[nil, 1, _("Sorry, the processing of `diff' command was interrupted because it has taken a lot of time.")]]
+         end)
 if diffs
   css = 'a'
 %>

なお、このパッチを含むWikiもどき 20050205.3版をリリースしますので、20050205.2版以前をお使いの方は20050205.3版への移行をお願いいたします。

wikimodoki-server利用時のユーザディレクトリ利用可能な不具合 (2005-10-08)

20050205.1版までのWikiもどきに含まれるHTTPサーバ(wikimodoki-server)には、意図しないユーザディレクトリの利用が行える不具合がありました。20050205.2版にて修正しましたので、対象となるバージョンをお使いの方は20050205.2版の利用をお願いいたします。

対象となるバージョン

Wikiもどき 20050205.1版より以前の全て。不具合の確認は20050205.1版にて行いました。

詳細

20050205.1版までは、以下の条件を満たす場合Apacheなど他のHTTPサーバが参照するファイルまたはCGIをwikimodoki-server経由で参照することが可能でした。

  1. Apacheなど他のHTTPサーバとwikimodoki-serverを同じIPアドレスを使って動作させている。
  2. 他のHTTPサーバの設定において、ユーザディレクトリを$HOME/public_htmlと設定している。

例えばApache2にてhttp://moonrock.jp/~don/を参照出来る状態で、wikimodoki-serverにてhttp://moonrock.jp:8888/wm3を用意しますと、http://moonrock.jp/~don/と同じものをhttp://moonrock.jp:8888/~don/として参照可能でした。

特にCGIの場合には他のHTTPサーバ用に用意した.htaccessなどによる認証処理を回避して実行する事ができました。

この不具合の動作自体はWEBrickの仕様として正しいものですが、Wikiもどきとしては想定しておりませんでした。

修正点

wikimodoki-serverではWEBrick::HTTPServerクラスを使用していますが、WEbrick::HTTPServer.newメソッドへのオプション指定が適切ではなかった為、ユーザディレクトリが利用可能な状態になっていました。

WEBrick::HTTPServer.newメソッドは通常以下のように使われますが、以下の状態ではユーザディレクトリ利用可能、かつCGI利用可能となります。

require "webrick"
# 変数optionsはHashオブジェクト。
s = WEBrick::HTTPServer.new(options)

これを回避する為、WEBrick::HTTPServer.newへのオプション:DocumentRootOptionsに:UserDir => nilを加えました。以下は加えた状態を示す例です。

s = WEBrick::HTTPServer.new({
  :DocumentRootOptions => {
    :UserDir => nil, # ユーザディレクトリは利用しない。
  },
})

これによりユーザディレクトリが利用されなくなります。

ページへ添付したファイルによる脆弱性 (2005-05-19)

Wikiもどきの添付ファイル機能を利用した脆弱性が発見されました。

添付ファイル機能とは、ユーザが任意のファイルをページへアップロードすることが可能な機能です。Wikiもどきではアップロードされるファイルに対して制限をしておりませんでした。その為、危険なファイルであってもアップロードが可能で、他のユーザがそれを閲覧または実行することが出来ました。

ここではその脆弱性の回避方法をお知らせいたします。

なおこの脆弱性は、株式会社ビジネス・アーキテクツ 太田 良典氏がIPAへ報告されました。それによりJPCERT/CCを通じて岩月へ報告をいただきました。発見者ならびにご協力いただいた方々に感謝いたします。

対象となるバージョン

Wikiもどき 20050205版より以前の全て。

ユーザによる回避策A

添付ファイル機能を無効にして下さい。2005-05-19現在、脆弱性を確実に回避するにはこの方法のみです。

手順

現在添付ファイル機能をお使いのサイトでは、wikimodoki-config.rbでの以下の設定に「-attach.rb」を追加します。これにより添付ファイル機能が停止します。

# プラグインリスト(*:全て許可 +foo.rb:許可 -foo.rb:不可)
PLUGIN_LIST = '* -attach.rb'

WEBrick HTTPServletとしてお使いの場合は、HTTPサーバ(wikimodoki-server)を再起動してください。

ユーザによる回避策B

また、新しく用意しました 20050205.1 版では添付ファイル機能の利用条件を制限する機能を追加しました。この機能をお使いいただくことで脆弱性をある程度回避することが出来ます。しかし、脆弱性を完全に回避するものではありませんので、ご使用には十分ご注意下さい。

手順

Wikiもどきを20050205.1版へアップデートします。

wikimodoki-config.rbでattach.rbを有効にします。もしもユーザによる回避策Aの回避策を行った場合はPLUGIN_LISTから「-attach.rb」を取り除きます。

# プラグインリスト(*:全て許可 +foo.rb:許可 -foo.rb:不可)
PLUGIN_LIST = '*'

wikimodoki-config.rbのDB_FILENAMEで指定したファイルと同じディレクトリにattach_config.yamlというファイルを作成、編集します。attach_config.yamlの詳細につきましては添付ファイル機能の利用制限をご覧下さい。

更新履歴

2005-05-20
  • 冒頭の謝辞を修正しました。

添付ファイル機能の利用制限 (2005-05-19)

ページへ添付したファイルによる脆弱性 (2005-05-19)におきまして、脆弱性への対処としまして添付ファイル機能の利用条件を定める機能を追加しました。

具体的には、アップロード時に以下のものについて確認して、条件を満たす場合にのみアップロードを許可します。

  1. アップロードを行おうとするユーザのホスト名
  2. アップロードされたファイルの名前
  3. アップロードされたファイルのContent-Type

導入手順

Wikiもどきを20050205.1版以降へアップデートします。

次にattach_config.yamlというテキストファイルをwikimodoki-config.rbのDB_FILENAME(データベースファイル)と同じディレクトリに用意します。用意されない場合は全てのファイルが許可された状態になりますのでご注意下さい。

設定ファイル

attach_config.yamlは、20050205.1版より添付ファイル機能に追加されたアクセス制御機能の為の設定ファイルです。

このファイルにはYAMLという書式を使って設定を書きます。

ファイル名による利用制限

書式は次の通りです。

filename:
- allow: (受け付けるファイルの名前)
- deny: (拒否するファイルの名前)

まず1行目の「filename:」は、ファイル名による利用制限を記述することを示します。ファイル名により利用制限を記述する場合には必ずこの行から書き始めます。

2行目は、行頭の「- allow:」までが「利用を許可するファイルの名前」を示します。コロン(:)以降に許可するファイルの名前を指定します。ファイル名に「all」を指定しますと全てのファイル名を許可することを明示します。

3行目は、行頭の「- deny:」までが「利用を拒否するファイルの名前」を示します。コロン(:)以降に拒否するファイルの名前を指定します。

いくつか例を挙げます。

以下のようにすると、ファイル名 foo.jpg のみ受け付けます。

filename:
- allow: foo.jpg
- deny: all

ファイル名の末尾が .jpg のみ受け付けます。ファイル名として正規表現が使えます。その場合「!ruby/regexp 」(最後に空白文字が必要)が必ず必要です。

filename:
- allow: !ruby/regexp /\.jpg\Z/i
- deny: all

ファイル名の末尾が .jpg と .png の2種類のみ受け付けます。正規表現を使って2種類の拡張子を一度に指定しています。

filename:
- allow: !ruby/regexp /\.(jpg|png)\Z/i
- deny: all

上記と同じくファイル名の末尾が .jpg と .png の二種類のみ受け付けます。「- allow:」や「- deny:」を複数行指定しますと、それら全ての条件が有効になります。

filename:
- allow: !ruby/regexp /\.jpg\Z/i
- allow: !ruby/regexp /\.png\Z/i
- deny: all

ファイル名 foo.jpg 以外を受け付けます。上記までは「- deny: all」でしたが、「- allow:」と同じくファイル名を指定できます。そのかわり「- allow: all」とすることで、残り全てのファイル名を許可しています。

filename:
- deny: foo.jpg
- allow: all

ホスト名による利用制限

ファイルをアップロードしようとするホストの名前もしくはIPアドレスを元に制限します。

書式は次の通りです。

host:
- allow: (受け付けるホストの名前)
- deny: (拒否するホストの名前)

ファイル名による利用制限同様「host:」という行から始めます。また、「- allow:」「- deny:」などもファイル名による利用制限と同様に機能します。

以下のようにすると、localhost からのみ受け付けます。

host:
- allow: localhost
- deny: all

もしくは以下のように指定する必要があるかもしれません。

host:
- allow: localhost
- allow: 127.0.0.1
- deny: all

複数のIPアドレスを一度に指定するいは正規表現を使います。以下のようにすると192.168.0.0/24からのみ受け付けます。

host:
- allow: !ruby/regexp /\A192\.168\.0\.\d+\Z/
- deny: all

誤って以下のように書きますと、ホスト名の先頭が 192.168.0. であるホスト(例えば 192.168.0.example.com)を全て受け付けてしまいますのでご注意下さい。

host:
- allow: !ruby/regexp /\A192\.168\.0\./
- deny: all

利用率が高いのは特定するホストからの利用を禁止することと思われますが、ホスト名は末尾からの一致で判断するようにします。正規表現の末尾の i を忘れると、ホスト名を大文字で使われた時に拒否しませんのでご注意下さい。

host:
- deny: !ruby/regexp /\.example.com\Z/i
- allow: all

Content-Typeによる利用制限

アップロードするファイルに対してブラウザがContent-Typeを指定する場合にのみ機能します。

書式は次の通りです。

content-type:
- allow: (受け付けるContent-Type)
- deny: (拒否するContent-Type)

「content-type:」という行から始めます。また、「- allow:」「- deny:」なども同様に機能します。

以下のようにすると、image/png のみ受け付けます。このようにすることでPNGファイルのみ受け付けることが出来るかもしれません。

content-type:
- allow: image/png
- deny: all

応用例

画像ファイルのみを受け付けるにはファイル名による利用制限Content-Typeによる利用制限を併用すると良いかもしれません。

filename:
- allow: !ruby/regexp /\.(jpg|png)\Z/i
- deny: all
content-type:
- allow: !ruby/regexp /\Aimage\//i
- deny: all