PEAK XOOPS - bashでWebアプリケーションを書く in englishin japanese

Archive | RSS |
PHP
PHP : bashでWebアプリケーションを書く
Poster : GIJOE on 2008-10-08 15:32:43 (16079 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でアップロードするのに四苦八苦していた人には朗報になるはずです。

次回を待て!


Printer friendly page Send this story to a friend

Comments list

tohokuaiki  Posted on 2008/10/9 13:42
これは、次回に超期待。
Login
Username or e-mail:

Password:

Remember Me

Lost Password?

Register now!