web-dev-qa-db-ja.com

メール送信前にPHP)でユーザー入力をサニタイズする方法は?

PHP経由で送信されたフォームから値を取得し、それらを私にメールする単純なPOSTメーラースクリプト:

<?php
$to = "[email protected]";

$name = $_POST['name'];
$message = $_POST['message'];
$email = $_POST['email'];

$body  =  "Person $name submitted a message: $message";
$subject = "A message has been submitted";

$headers = 'From: ' . $email;

mail($to, $subject, $body, $headers);

header("Location: http://example.com/thanks");
?>

入力をサニタイズするにはどうすればよいですか?

47
Matt Hampel

filter_var() を使用してpost変数を無害化します。

ここの例 。お気に入り:

echo filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);   
52
Haim Evgi

ここではSQLクエリなどを作成していないので、これらの入力について確認できる唯一の関連する検証は、$ _ POST ["email"]の電子メール検証であり、本当に必要な場合は、他のフィールドの英数字フィルターを使用することもできますメッセージに含めることができる内容の範囲を制限します。

メールアドレスをフィルタリングするには、単純に filter_var を使用します。

$email = filter_var($email, FILTER_SANITIZE_EMAIL);

Frank Farmerの提案に従って、メールの件名の改行を除外することもできます。

$subject = str_replace(array("\r","\n"),array(" "," "),$subject);
12
Wadih M.

他の人が指摘したように、 _filter_var_ は素晴らしいです。利用できない場合は、ツールチェストに追加してください。

_$headers_変数は、セキュリティ面で特に悪いです。これを追加して、スプーフィングされたヘッダーを追加できます。 Email Injection と呼ばれるこの投稿は、それについてかなりよく議論しています。

_filter_var i_ s素晴らしいですが、何かがメールアドレスであり、悪いものではないことを保証する別の方法は、isMail()関数を使用することです。ここに一つあります:

_function isEmail($email) {
    return preg_match('|^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+$|i', $email);
};
_

これを使用するには、次のようにします。

_if (isset($_POST['email']) && isEmail($_POST['email'])) {
    $email = $_POST['email'] ;
} else {
    // you could halt execution here, set $email to a default email address
    // display an error, redirect, or some combination here,
}
_

手動検証の観点から、 substr() を使用して長さを制限し、 strip_tags() を実行して、それ以外に入力できるものを制限します。

4
artlung

$ headersでユーザーが提供する入力から改行を削除する必要があります。これは、mail()(この場合は$ email)に渡されます! メールの挿入 を参照してください。

PHPは$ toおよび$ subjectのサニタイズを処理する必要がありますが、PHPバグのあるバージョンがあります(影響を受けるのはPHP 4 <= 4.4.6および= PHP 5 <= 5.2.1、参照 MOPB-34-2007 )。

4
blueyed

上記のartlungの回答のコードを使用して、メールを検証できます。

私はこの種のコードを使用して、ヘッダーインジェクションを防ぎます。

_// define some mail() header's parts and commonly used spam code to filter using preg_match
$match = "/(from\:|to\:|bcc\:|cc\:|content\-type\:|mime\-version\:|subject\:|x\-mailer\:|reply\-to\:|\%0a|\%0b)/i";

// check if any field's value containing the one or more of the code above
if (preg_match($match, $name) || preg_match( $match, $message) || preg_match( $match, $email)) {

// I use ajax, so I call the string below and send it to js file to check whether the email is failed to send or not
echo "failed";

// If you are not using ajax, then you can redirect it with php header function i.e: header("Location: http://example.com/anypage/");

// stop the script before it reach or executing the mail function
die();

}
_

上記のmail()のヘッダーフィルタリングは厳格すぎます。一部のユーザーは、メールフォームをハイジャックする意図なしにメッセージでフィルタリングされた文字列を使用している可能性があるため、その文字列の種類を説明しているページにリダイレクトします。フォームでの使用、またはフォームページでの説明は許可されていません。

1
KeepMove