PEAK XOOPS - News in englishin japanese

Archive | RSS |
  
Poster : GIJOE on 2008-10-30 16:04:51 (7005 reads)

in englishin japanese
Snoopyにコマンド実行脆弱性が見つかっています。
http://jvn.jp/jp/JVN20502807/

現実には、XOOPS各フォークのコアで、任意のURIをSnoopyに渡す、ということはありませんし、各モジュールについても、Snoopyで取得するURIについては、管理者以外は指定できないものがほとんどだと思うので、ほぼすべてのXOOPSサイトでそれほどの緊急性はないでしょう。慌てず騒がず、今後でてくる新バージョンにバージョンアップすれば十分です。

ただ、もし、ゲストが投稿したURIからRSSやサイトイメージを取得しようとするような使い方をしているのなら、緊急性があります。いますぐパッチを当ててください。

なお、Snoopyを自前で持っているモジュールには、xhldがあります。こちらについても、とりいそぎパッチを当てておきます。d3pipes は自前で持っていないので、コアの方だけパッチを当てれば十分です。

それにしても、$safer_URIなんてのが全然安全じゃなかったことに、1.2.3パッチの時点で気付けなかった自分が恥ずかしい…


Index: html/class/snoopy.php
===================================================================
--- snoopy.php  (revision 729)
+++ snoopy.php  (working copy)
@@ -1035,8 +1035,7 @@

                $headerfile = tempnam($temp_dir, "sno");

-               $safer_URI = strtr( $URI, "\"", " " ); // strip quotes from the URI to avoid shell access
-               exec($this->curl_path." -D \"$headerfile\"".$cmdline_params." \"".$safer_URI."\"",$results,$return);
+               exec($this->curl_path." -k -D \"$headerfile\"".$cmdline_params." \"".escapeshellcmd($URI)."\"",$results,$return);

                if($return)
                {

0 comments

Poster : GIJOE on 2008-10-15 16:28:42 (12406 reads)

in englishin japanese
XOOPS2.0.4から導入されて「しまった」XoopsErrorHandler。
私自身、ことある毎にこれについて批判してきましたが、その理由は明確です。

(1) phpの設定によらず、PHPエラーがHTTPボディとしてechoされてしまう
(2) fatalエラーなどで止まる場合は、ハンドラの上書きが効かない
(3) mainfile.phpを通過するケースとそうでないケースで、設定を一致させる術がない

(1)は、実稼働サイトでエラーを確認する術がないことを意味します。XoopsErrorHandlerは一応XOOPS_URLを隠蔽してくれますが、PHPデバッグがONの間、すべての訪問者にエラー内容を送出してしまう、という根本的な問題が解決されていません。

(2)も大きな問題です。mainfile.phpなどの記述ミスで、fatalエラーとなる場合、error_reporting()やXoopsErrorHandlerの処理など実行されないのですから、必然的にphpの設定がそのまま生きます。

(3)は(2)と似ていますが、これはPathDisclosure問題と直結します。XOOPSの構造は古く、本来DocumentRoot外に置かれるべきPHPコードの断片ファイル群が、DocumentRoot内に多く存在します。それらに直アクセスされた時に、PathDisclosureとなるかどうかは、php設定によるのです。

つまり、どのようなエラーハンドラ設計を行おうと、php設定こそが重要である、という事実はひっくり返しようがないのです。

であれば、特定条件を満たした時だけ働くエラーハンドラなど無効にして、PHP設定だけですべてをコントロールできるようにするのが合理的な手段というものでしょう。

特に勝手にerror_reporting()レベルを変更してしまうXoopsErrorHandlerなんて、今すぐ捨てましょう!


…と、ここで従来であれば、「その部分を潰すHackは〜」となるわけですが、XCL2.1なら、それさえもpreload一個で実現できることに、今になってようやく気付きました。

XCL2.1用のエラーハンドラ正常化preload
http://www.peak.ne.jp/support/xoops/Preload_ErrorHandlerOriginal.zip
(解凍で得られた ErrorHandlerOriginal.class.php を preloadフォルダにコピー)

このpreloadを入れるだけで、php設定だけでエラー処理をすべてコントロール出来るようになります。


なお、ほとんどすべてのケースで都合が良いのは、エラーをログに記録する方法です。
「ログ記録方式だとリアルタイムなデバッグに使いづらいじゃないか」なんていう人には、良い方法を教えましょう。好きなターミナルを開いておいて、
$ tail -f error_log
とするだけです。tailの-fオプションは様々な局面で役立つので、絶対に暗記しておくべきでしょう。

もしあなたがXCL-2.1を利用しているのなら、上述したpreloadを有効にした上で、php.iniや.htaccessで、エラーをロギングするようにしましょう(log_errorsをonにして、error_logに適切なファイルを指定)。もちろん、display_errorsはoffです。

それこそが、開発者にとって最も効率よい環境であり、同時に、サイト運営者にとって最も安全な環境ですから。

0 comments

Poster : GIJOE on 2008-10-09 17:45:23 (15459 reads)

in englishin japanese

●アプリケーションインストーラの原理等

前の記事でも書いたのですが、rsync+sshやsshログインが出来ない環境で、大量のファイルを展開するWebアプリケーションのセットアップは、かなり辛いものがあります。FTPでアップロードするのにもとても時間がかかり、途中で切れることも珍しくありません。アップロードが不完全であることに気がつければまだ良い方で、成功したと思い込んで作業を進めてしまうと、後になってから面倒なトラブルが頻出することになります。

しかし、そういう環境(安価な共有型ホスティングサービス)であれば、おそらくCGIはsuExecです。であれば、アーカイブの展開をCGIでやってしまえば良いのです。ファイルオーナーはFTPでアップするのと一緒です。つまり、FTPで大量のファイルをアップロードする必要なんてなくなります。

ついでに、アーカイブもwgetで取得してしまえば、FTPでアップロードするのは、そのCGIのみとなります。そうなれば本当に楽ちんです。

ここで注意しなければならないのは、wgetのパラメータが任意ではいけません。そんなことをしたら、そのCGIが存在しているタイミングに、任意のアプリケーションをインストールされてしまいます。(もちろん、そうであってもなくても、そのCGIは実行後、即座に消すべきですが)


とりあえず、サンプル的な意味で、ホダ塾ディストリビューションをインストールするためのCGIを書いてみました。

http://www.peak.ne.jp/support/xoops/hd_installer.zip

●bashCGI版インストーラ使い方

このファイルを解凍すると、hd_installer.cgi というファイルが出来ますので、これをサーバにFTPでアップロードします。アップロード先が重要で、XCLのルートフォルダとなるべきフォルダにアップロードしなければなりません。

例えば、サーバのDocumentRootが /home/foo/public_html で、そのルートにインストールしたいのであれば、そのまま /home/foo/public_html の下にアップします。
このファイルはCGIですから、実行パーミッションを与えます。755または705が一般的でしょう。また、サーバによっては、.htaccess に
Options +ExecCGI
の一行を追加する必要があるかもしれません。

あとは、ブラウザで、そのCGIにアクセスするだけです。例えば、
http://www.example.com/hd_installer.cgi
など。

あとは画面に表示される手順に従うだけで、インストーラ画面が開きます。tar.gzアーカイブを、パーミッション保存したまま展開するので、cache, uploads, mainfile.php などのパーミッションをFTPで変更する必要すらありません。「5分でインストール」どころか2分を切れそうです

一度遊びで試してみれば、その簡単さに驚くはずです。

ただ、「遊び」とは言っても、ローカルでテストしたら、たいがいうまく行きません。xampp環境ではそもそもbashがないでしょうし、自宅サーバなどに*nixをインストールして開発に使っているケースでも、ちゃんとsuExecを有効にしていることはほとんどないでしょう。このCGIは、suExecを有効にしている共有型レンタルサーバでないと動かないし動かす意味もない、ということをお忘れなく。


●余談

wgetで取得可能なアーカイブは、 http://downloads.sourceforge.net/hodajuku/ 直下のファイルに限定されます。ただ、サーバがファイルをリモートから取ってくる形ではなく、CGIと同一フォルダにアーカイブを用意しておけば、一部のモジュールのインストールにも利用可能です。少なくとも私のD3モジュールであれば、そのまま行けます。(もっとも、そのほとんどがHDに同梱されているのでほとんど意味はありませんが)

なお、XCL2.1.xはなぜかzipしか用意がないので、この手が使えません。もちろん、unzipコマンドを使えば解凍できるので、そのようにCGIを改変すれば良いのですが、unzipはあまり一般的ではないので、そういうコードにしていません。さらにzipにはパーミッションの概念がないので、解凍したファイル群に対するパーミッション変更までCGIに記述する必要があります。


このタイプのインストーラに興味があるなら、ぜひhd_installer.cgiを改変してください。
スパゲッティになりやすいbashスクリプトにしては、そこそこ見やすく再利用しやすいコードとなるよう努力したつもりです。スクリプトの最初の方にある定数定義だけいじれば、ImpressCMSや本家版XOOPSにも利用できるでしょう。再利用しやすいように、ライセンスも修正BSDとしてあります。


今回はインストーラでしたが、このシステムが本当に効いてくるのは、むしろアップデータでしょう。大量のファイルをFTPで上書きアップロードするというのは、本当に面倒です。しかもインストール時よりもさらに、途中で切れたかどうかの判断が難しくなります。

さらに、アップデータであれば、インストールされた情報(XOOPSであればmainfile.php)を参考にすることが出来るので、インストーラのようにリクエストに依存する必要がなくなります。つまり、サーバに置きっぱなしでも良いようなCGIを作れる可能性はあります。

次回はそのアップデータを作ってみたいと思います。


Poster : GIJOE on 2008-10-08 15:32:43 (12873 reads)

in englishin japanese
私自身もともとPrimitiveな環境での実験が好きなのですが、今回、Webアプリケーション(というかちょっとしたCGI)をbashで書くことをいろいろと試してみました。(もちろん、Webサーバはapache)

結論を先に書くと、「そんな馬鹿なことはやめなさい」で終わりです。
perlがどれだけ素晴らしいツールであるか、身を持って知った気がします。

ただ、あえてbashで書く、というのにはそれなりの動機付けがあります。
perlだと、モジュールの有無でいろいろと動作環境問題が出がちですが、bashであれば、普通の*nixにはほぼ100%インストールされてますし、環境問題も出づらいでしょう。(もちろん、使うコマンドにもよりますが)

環境差によるハマリをさけるため、使って良いコマンドも極力、絞ります。
比較的高機能なコマンドはsedくらいでしょうか。
'perl -ne' などが使えたら相当に楽なのですが、あえてperlは一切使わずに頑張ります。

以下、bashでCGIを書くときの注意点と対策を列挙します。

・必ずHTTPレスポンスを返す
HTTPレスポンスを返さないと、500エラーとして扱われます。
ヘッダの各行は、基本的にechoで直書きします。
もちろん、ヘッダとボディは空行で区切ります。

・echo -e オプションを忘れないこと
これがないと、コードが書きづらいでしょう。

・リクエスト受取方法
GET変数は$QUERY_STRINGを分解することで得られます。POST変数は標準入力をいったん変数に受け取ってから分解します。分解はbashのパターン照合を駆使します。


	query="$QUERY_STRING&"
	until [ -z "$query" ] ; do
		k_v=${query%%&*}
		query=${query#*&}
		key=${k_v%%=*}
		value=${k_v#*=}
	done

こんな感じで、$keyと$valueの対が得られます…が(続く)

・bashには連想配列がない!
とにかくこれが辛いです。連想配列がないために、リクエストのkeyとvalueの対をスマートに保存する術がありません。私自身さんざん悩んだのですが、REQUEST_(key) という形の変数をリクエスト専用の文字空間として利用することで、擬似的に連想配列を実装(?)しています。

・簡単にセキュリティホールが出来る
PHPは穴を作りやすい開発言語と言われて久しいですが、bashに比べたら可愛いものだと言わざるを得ないでしょう。
なぜなら、bashのCGIでは、ちょっとミスしただけでも、簡単にコマンドインジェクション脆弱性が確定しますから。外部コマンドに対して、変数が展開されてから渡されるのか、それともクオーティングされたまま渡されるのか、ちゃんと把握しないと、それだけで即死です。

・HTMLエスケープするスマートな手段がない
これも相当に困ります。bashの関数は、戻り値を文字列とすることが難しいので、文字列を変換する関数が事実上作れません。
これについても、良い方法が思い浮かばなかったので、変数に '"&<> が含まれないようにする、という消極的な手段を取りました。
リクエストを受け取る時に、[a-zA-Z0-9._-] 以外のキャラクターを全部消す、という処理を共通にかけています。
逆に言えば、複雑なテキストを受け取る可能性があるWebアプリケーションはbashで作ってはいけない、ということでしょう。


…と、ここまで読む限りでは、すべてが無駄な努力のように思えますが、実はbashでCGIを作ることで、PHPアプリケーションのインストールやアップデートがとても簡単になるのです。sshの使えない共有型レンタルサーバで、大量のファイルをFTPでアップロードするのに四苦八苦していた人には朗報になるはずです。

次回を待て!


Poster : GIJOE on 2008-09-12 17:23:54 (7469 reads)

in englishin japanese
最近、こんな書籍を監訳しました。


HP SoftwareのBilly HoffmanとBryan Sullivan両氏による"Ajax Security" (Addison-Wesley) が原著です。

基本的には、渡邉さんの手による和訳文を読んで、日本語として判りづらいところや技術的におかしなところに突っ込みを入れる、という作業がほとんどでしたが、原著自体がなかなか面白く、楽しんで仕事ができました。

毎コミのぽち@さんに「宣伝しておきますね」と安請け合いしておきながらナニですが、ぶっちゃけ、この書籍高いです。
5,040円もします。(元が$49.99だということを考えれば、意外と安いとも言えます)
個人レベルではなかなか購入できないでしょう。

でも、職業としてWebプログラマーをやっている人なら、一度目を通しておいても損はしないだろう、と思えるレベルの書籍だと思います。
Web開発系会社の社長さん、ぜひ御社のプログラマーやテスタに買い与えてやってください

この書籍は特にJavaScript系の攻撃に詳しく、そういう落とし穴を事前に知っておくだけでも、今後のキャリアに役立つはずです。
「オレオレ詐欺(振込め詐欺)」だって、その手口を知っているのと知らないのとでは、引っかかってしまう危険性は雲泥の差でしょう。

ついでに、これまた正直に書いておくと、原著には結構突っ込みどころが多く存在してました。
ただ、それらについては、極力、訳註という形でフォローしてますので、トータルではそれなりのレベルには仕上がっていると思います。
もちろん、私のつけた訳註そのものが間違っている可能性もありますが、万一その場合は正誤表を載せる方向でご容赦ください

すでにAmazon様にも登録されていて、9/26発売だそうです。
(Amazonの方が監訳者よりよほど詳しい!
<姑息なアフィリエイトリンク>

# ちなみに表紙は、アヤックス(AFC Ajax)のディフェンダーです
# ちゃんと急所をおさえているとこに注目!

0 comments

« 1 2 3 (4) 5 6 7 ... 55 »
Login
Username or e-mail:

Password:

Remember Me

Lost Password?

Register now!