Jak wyczyścić wejście użytkownika w PHP przed mailingiem?

Mam prosty skrypt PHP mailer, który pobiera wartości z formularza przesłanego pocztą i wysyła je do mnie:

<?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");
?>

Jak mogę odkażać wejście?

Author: Matt Hampel, 2009-06-28

5 answers

Dezynfekcja zmiennej post z filter_var().

Przykład tutaj . Like:

echo filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);   
 46
Author: Haim Evgi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-17 01:11:06

Ponieważ nie budujesz zapytania SQL lub czegokolwiek tutaj, jedyną istotną walidacją, którą widzę dla tych danych wejściowych, jest Walidacja wiadomości e-mail dla $_POST ["email"], a może filtr alfanumeryczny na innych polach, jeśli naprawdę chcesz ograniczyć zakres tego, co wiadomość może zawierać.

Aby filtrować adres e-mail, po prostu użyj filter_var :

$email = filter_var($email, FILTER_SANITIZE_EMAIL);

Zgodnie z sugestią Franka farmera, możesz również odfiltrować nowe linie w temacie wiadomości e-mail:

$subject = str_replace(array("\r","\n"),array(" "," "),$subject);
 12
Author: Wadih M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-28 18:57:15

Jak zauważyli inni, filter_var świetnie. Jeśli nie jest dostępna, dodaj ją do zestawu narzędzi.

Zmienna $headers jest szczególnie zła pod względem bezpieczeństwa. Może być dołączany i powodować dodawanie fałszywych nagłówków. Ten post o nazwie email Injection omawia go całkiem dobrze.

filter_var is super, ale innym sposobem zapewnienia, że coś jest adresem e-mail, a nie czymś złym jest użycie funkcji isMail(). Oto jeden:

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

Więc aby użyć tego, ty można:

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,
}

Jeśli chodzi o ręczną walidację, ograniczając długość za pomocą substr(), bieganie strip_tags() i w przeciwnym razie ograniczając to, co można umieścić.

 4
Author: artlung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-28 20:24:53

Musisz usunąć wszystkie nowe linie z danych wejściowych podanych przez użytkowników w $headers, które zostaną przekazane do mail () ($email w Twoim przypadku)! Zobacz email injection .

PHP powinno zająć się oczyszczaniem $to i $subject, ale są wersje PHP z błędami (dotyczy to PHP 4 Mobb-34-2007).

 4
Author: blueyed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-25 16:59:59

Możesz użyć kodu z odpowiedzi artlung powyżej, aby zweryfikować wiadomość e-mail..

Używam tego rodzaju kodu, aby zapobiec wtryskiwaniu nagłówka..

// 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();

}

Powyższe filtrowanie nagłówków mail() jest zbyt rygorystyczne, ponieważ niektórzy użytkownicy mogą używać filtrowanych ciągów w swojej wiadomości bez zamiaru przejmowania formularza e-mail, więc przekieruj go na stronę wyjaśniającą, jakiego rodzaju ciągi nie są dozwolone w formularzu lub wyjaśnij to na stronie formularza.

 0
Author: KeepMove,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-09 13:19:51