Diary?

2008-02-03
Sun

(03:12)

ここ一週間程、前の現場の引き継ぎだとか友人の修論手伝ったりとかで忙しくて、ろくすっぽギターに触っていなくてこりゃあヤベエと思ってこんな時間に練習開始。……流石に一週間もサボると衰えるなあ。これだから中々上達せんのだよ、俺は。

(20:03)

今朝は起きたら大変なことになってた。何だよこの雪は。あまりの寒さに生きる気力が失われていくようだ。

それはともかく、すげえ今更なんだけど PHP はダメ言語かどうかについて。ダメかダメじゃないかの二択で答えろって言われたら即座に「ダメ」と答えるんだが、多分そんなことよりももっと重要というか一番ダメなのは「PHP で簡単に Web アプリ」とかいってる連中で、まあこれは PHP に限った話じゃないか。実際のところ、初心者が適当に作った Web アプリでも被害が出ることはあるんだからな。

すげぇ適当な事例を書くと、次の cgi スクリプト (の一部) は spam 送信に悪用可能である。公平性のため、俺にとって第二の母国語である Python で書いておく (PHP で書いたら電波がよってきそうだからな!)。

from cgi import FieldStorage
from email.mime.text import MIMEText
f = FieldStorage()
subj = f['subject'].value
from = f['from'].value
msg = f['msg'].value
m = MIMEText(msg)
m['Subject'] = subj
m['From'] = from
m['To'] = 'admin@example.com'

さて、ここで送信されたデータのうちの "from" でも "subject" でもいいから、次のようなデータが入っていたらどうする?

foo@example.net\nBcc: bar@example.org

これを受け取った状態で MIMEText の as_string を呼び出すと、次の様な結果になる。

Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Subject
From: hoge@example.net
Bcc: foo@example.org <- 見事に Bcc が追加されてる
To: admin@example.com
-- 以下、メール本文 --

これはヘッダインジェクションという奴だ。一見すると単に入力データに改行が含まれていないかどうかだけのチェックをすれば良さそうだけど、実は長すぎるヘッダには折り返しを行うようにと RFC には書かれていて、そこで折り返し処理の書き方次第では、この部分でヘッダインジェクションを行うという事が出来てしまう (実際には今の MTA は大抵長いヘッダを問題なく処理できるはずだけど)。なので、ヘッダインジェクションのチェックというのは思っているよか面倒くさいわけだ。ところで今はどうだか知らないけど、 PHP のメール関連の関数には先に出した折り返し処理に関連する脆弱性があったはずだ。 Python は email.Header がこの折り返し処理とかには対応している。他の言語は知らない。

追記: Python の email.Header はあくまでも長いヘッダの折り返しだけなんで、それ以外のことはやっぱり個々のプログラマがやんないとダメ。ところでこの折り返し処理って、 Django の email 系の処理ともろに競合していて、 email.Header で折り返しの付けられたヘッダを Django 側が削除しちゃうって話を聞いたことがある。その後どうなったのかは知らない (この手のフレームワークを使う事にあんま興味ないんで)。

ちなみにこれはメールフォーム CGI で起こりうることで、ちょっと見栄張って自分で作ったメールフォームを設置したら spam 送信に使われちゃいましたなんて笑えない事態もありうるわけだ。なので、あんまり「簡単に作れます」と吹聴するのはなあ。事実、これと同じかどうかは知らないけど XOOPS とかのメジャーなアプリケーションでも spam の踏み台にされるような問題があったり、共用サーバとかだとさらに DB や Web サーバの権限とか、いろんな問題があるわけだ。なので俺は「初心者はPHPで脆弱なウェブアプリをどんどん量産すべし」なんてことは口が裂けても言えない。

とりあえず俺に言えることは、

  • ネットワークアプリケーションは「簡単にできる」という謳い文句とは程遠い代物だ
  • その性質上、他人に迷惑をかけないようにネットワークアプリケーション開発を学ぶのは大変だ
  • あまりに「簡単に出来ます」と言ってる連中は詐欺師か恥知らずかその両方かだ
  • PHP は今のところバージョンに限らず最初に覚えるべき言語ではない (将来大幅にレベルアップする可能性はゼロじゃないけど)

程度だ。

Creative Commons
この怪文書はクリエイティブ・コモンズ・ライセンスの元でライセンスされています。引用した文章など Kuwata Chikara に著作権のないものについては、それらの著作権保持者に帰属します。