PHPプログラムからメール送信する場合、mb_send_mailなどのPHP関数を使うことがある。
mb_send_mail関数は引数にメール送信先、送信元などの値を取るが、この時ユーザーの入力値を引数に取る際にメールヘッダインジェクションを仕掛けられる場合がある。
メールヘッダインジェクションは攻撃の手口としてはシンプルなもので、例えば氏名・メールアドレスなどの情報を入力するフォームで、メールアドレス入力欄に改行を含めることでメールヘッダを自在に改竄してしまうといったものだ。
メールヘッダを改竄されると、意図しない宛先へメールが送信され、また本文も改竄されるケースもあるため、迷惑メールの送信先として悪用されてしまうことになる。
メールヘッダインジェクションの根本的な対策
まず根本的な対策として、メール送信処理については数多あるPHPライブラリ(PHPMailerなど)を使うことが有効だ。
ライブラリにはユーザーの入力値を正しくバリデーションする処理が元々入っていることが多いためだ。
mb_send_mail関数を使ってメール送信をおこなう場合、自分でバリデーション処理を実装しなければならない。
バリデーションは後述の通り、そこまで難しくないのだがついつい忘れてしまうと脆弱性の元となる。
そのため、可能な限りメール送信処理を実装する場合はライブラリを使用する方が良い。
入力値から改行を除去してバリデーションする
Webアプリケーションにおいて、ユーザーからの入力値をそのまま利用せず、必ずバリデーションをおこなうことが鉄則だが、メールヘッダインジェクション対策としてのバリデーションを考えた場合、改行を除去することが必要だ。
$mail = str_replace(array('\r\n', '\r', '\n'), '', $_POST['mail']);
上記は改行コードを全て除去する処理だが、以下のように制御文字全てを除去してしまっても良いだろう。
$mail = preg_replace('/[[:cntrl:]]/u', '', $_POST['mail']);