はじめに
現在、PHP を学習中で、フレームワークとして CakePHP も学習しているのですが、CakePHP 2.2.0 の時にはメールヘッダインジェクションの脆弱性があると以下の書籍で読んで、ちょっと衝撃を受けているところです。自分でメールヘッダの改行コードを削除する必要があります。フレームワークが脆弱性を起きないようにする仕組みを持っていないということに驚きました。
ちなみに、以下の書籍は CakePHP 2 なので少し内容が古いですが、CakePHP 3 のよい書籍がない中では、この書籍から CakePHP を勉強するとよいのではないかなと思います。
メールヘッダインジェクションについて
現在の最新版でもメールヘッダインジェクションの脆弱性が残っているのか気になって調べてみました。きっかけは、PHP 5.4.0 の header 関数でヘッダインジェクションの脆弱性が解消したという話があったからです。
そこで、CakePHP 2.x 系の最新版の CakePHP 2.7.8 を調べたところ、ヘッダーに改行コードを挿入しても削除されるようになっていました。メールアドレスは正規表現でチェックがされるので、改行コードが入ることはありません。
これは mail 関数がヘッダーの改行コードを置換するようになったのか気になり、ソースコードをあったってみたところ、メール送信前にプログラムで改行コードを空文字列に変換していることが分かりました。
◆CakePHP 2.7.8 lib/Cake/Network/Email/MailTransport.php の MailTransport クラス
/** * Send mail * * @param CakeEmail $email CakeEmail * @return array * @throws SocketException When mail cannot be sent. */ public function send(CakeEmail $email) { $eol = PHP_EOL; if (isset($this->_config['eol'])) { $eol = $this->_config['eol']; } $headers = $email->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc')); $to = $headers['To']; unset($headers['To']); foreach ($headers as $key => $header) { $headers[$key] = str_replace(array("\r", "\n"), '', $header); } $headers = $this->_headersToString($headers, $eol); $subject = str_replace(array("\r", "\n"), '', $email->subject()); $to = str_replace(array("\r", "\n"), '', $to); $message = implode($eol, $email->message()); $params = isset($this->_config['additionalParameters']) ? $this->_config['additionalParameters'] : null; $this->_mail($to, $subject, $message, $headers, $params); return array('headers' => $headers, 'message' => $message); }
このように、改行コードの変換を行っているので、メールヘッダインジェクションの脆弱性がない訳ですね。
また、以下のバージョンの CakePHP でも同様の処理がなされていました。
- CakePHP 2.6.12 – 2.6.x 系の最新
- lib/Cake/Network/Email/MailTransport.php の MailTransport クラスの send メソッド
- CakePHP 3.1.5 – 3.1.x 系の最新
- src/Mailer/Transport/MailTransport.php の MailTransport クラスの send メソッド
CakePHP 3.1.x ではディレクトリ階層が変わっていましたが、内容は同じことを行っていました。
なお、CakePHP 1.x はさすがに古いのと、メーラーをプラグインで用意する必要があるので、調査対象から外しました。
まとめ
いつからメールヘッダインジェクションの対策がなされたのか不明ですが、少なくとも以下のバージョン以降ではメールヘッダインジェクションの対策を行わなくても脆弱性は発生しません。
- CakePHP 3.1.5 以降
- CakePHP 2.7.8 以降
- CakePHP 2.6.12 以降
なお、メールヘッダインジェクション対策でヘッダーの改行コードを空文字列に置換するというのは、害はないし安心でもあるでしょうから 、今後も行っていってもよいと思います。
コメント