環境
- Debian9
- PHP7
- nginx/1.14.0
- exim4.91
webページはすでに公開している。PHPも動く。
mailコマンドでeximからgmailにメール送信できている。
HTML
下記の<form>を書く
mail.html
<form name="contact" method="POST" action="mail.php">
<p>
<label> 名前:<br> <input type="text" name="name" id="input_name"/></label>
</p>
<p>
<label> メールアドレス:<br> <input type="email" name="email"id="input_mail"></label>
</p>
<p>
<label> 件名:<br> <input type="text" name="subject" id="input_subject"></label>
</p>
<p>
<label> 問い合わせ内容:<br> <textarea name="message" id="text_content"></textarea></label>
</p>
<p>
<button type="submit">送信</button>
</p>
PHP
mail.php
<?php
$message = "name: " . $_POST["name"] . "\nsubject: " . $_POST["subject"] . "\nfrom: " . $_POST["email"] . "\nbody: \n" . $_POST["message"];
if (!mb_send_mail("test@gmail.com", $_POST["subject"], $message)) {
exit("error");
}
?>
ブラウザでmail.htmlにアクセスして、gmailに送信されるか確認する
注意
- PHPの
mail()
およびmb_send_mail()
は第4引数以降に追加パラメータを設定できるが、これらは適切にエスケープしないと不正なコマンドをsendmail(mail)コマンドに渡される危険性があるらしい。そのため今回は第4以降を使用しなかった。
(2019/02/21追記)エスケープする
How to sanitze user input in PHP before mailing?にある回答よるとメールのタイトルに改行コードが入るのを許すと任意のメールヘッダを追加される恐れがある。これを防ぐために$_POST["subject"]
をエスケープして使う。
mail.php
<?php
$message = "name: " . $_POST["name"] . "\nsubject: " . $_POST["subject"] . "\nfrom: " . $_POST["email"] . "\nbody: \n" . $_POST["message"];
$safe_subject = str_replace(array("\r","\n"),array(" "," "), $_POST["subject"]);
if (!mb_send_mail("test@gmail.com", $safe_subject , $message)) {
exit("error");
}
?>
以下、エスケープについてのメモ
- メール本文はエスケープする必要はない。
- 宛先メールアドレスをユーザに入力させるときは
filter_var()
を使う。
filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
-
htmlspecialchars()
はHTMLに出力するときのエスケープであり、メール(やサーバ上でのコマンド実行)には関係ない。
この節の参考文献:
参考
PHPでメールフォームから宛先(Gmail)へ送信できない
[Why mail() is dangerous in PHP]
(https://blog.ripstech.com/2017/why-mail-is-dangerous-in-php/)
mb_send_mail(),mail()で第5引数を設定する際の注意点