php-est Filtre SANITIZE e-mail inutile?

Je ne fais que créer un formulaire d'inscription, et je ne cherche qu'à insérer des e-mails valides et sûrs dans la base de données.

plusieurs sites (y compris w3schools) recommandent d'exécuter FILTER_SANITIZE_EMAIL avant D'exécuter FILTER_VALIDATE_EMAIL pour être sûr; cependant, cela pourrait changer le courriel soumis d'un non valide en un courriel valide, qui ne pourrait pas être ce que l'utilisateur voulait, par exemple:

l'Utilisateur a l'adresse email jeff!@gmail.com, mais insère accidentellement jeff " @gmail.com.

FILTER_SANITIZE_EMAIL supprimerait le " making the email jeff@gmail.com ce que FILTER_VALIDATE_EMAIL dirait est valide même si ce n'est pas l'adresse e-mail réelle de l'utilisateur.

pour éviter ce problème, Je ne prévois d'exécuter que FILTER_VALIDATE_EMAIL. (en supposant que je n'ai pas l'intention de produire/traiter des e-mails déclarés invalides)

ceci me dira si l'email est valide ou non. S'il l'est, il ne devrait pas être nécessaire de passer à travers FILTER_SANITIZE _EMAIL parce que tout caractère illégal / dangereux, aurait déjà causé le retour de l'email invalide, correct?

Je ne connais pas non plus d'e-mail approuvé comme valide par FILTER_VALIDATE_EMAIL qui pourrait être utilisé pour injection/xss en raison du fait que les espaces blancs, les parenthèses () et les points-virgule invalideraient l'e-mail. Ou je me trompe?

(note: je vais utiliser des déclarations préparées pour insérer les données en plus de cela, je voulais juste clarifier ceci jusqu')

19
demandé sur jbrahy 2011-09-03 05:52:44

4 réponses

Voici Comment insérer seulement des e-mails valides.

<?php
$original_email = 'jeff"@gmail.com';

$clean_email = filter_var($original_email,FILTER_SANITIZE_EMAIL);

if ($original_email == $clean_email && filter_var($original_email,FILTER_VALIDATE_EMAIL)){
   // now you know the original email was safe to insert.
   // insert into database code go here. 
}

FILTER_VALIDATE_EMAIL et FILTER_SANITIZE_EMAIL sont à la fois des fonctions précieuses et ont des utilisations différentes.

la Validation teste si le courriel est un format valide. Nettoyer est de nettoyer les mauvais caractères hors de l'e-mail.

<?php
$email = "test@hostname.com"; 
$clean_email = "";

if (filter_var($email,FILTER_VALIDATE_EMAIL)){
    $clean_email =  filter_var($email,FILTER_SANITIZE_EMAIL);
} 

// another implementation by request. Which is the way I would suggest
// using the filters. Clean the content and then make sure it's valid 
// before you use it. 

$email = "test@hostname.com"; 
$clean_email = filter_var($email,FILTER_SANITIZE_EMAIL);

if (filter_var($clean_email,FILTER_VALIDATE_EMAIL)){
    // email is valid and ready for use
} else {
    // email is invalid and should be rejected
}

PHP est open source, donc il est facile de répondre à ces questions en l'utilisant.

Source pour FILTER_SANITIZE_EMAIL:

/* {{{ php_filter_email */
#define SAFE        "$-_.+"
#define EXTRA       "!*'(),"
#define NATIONAL    "{}|\^~[]`"
#define PUNCTUATION "<>#%\""
#define RESERVED    ";/?:@&="

void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL)
{
    /* Check section 6 of rfc 822 http://www.faqs.org/rfcs/rfc822.html */
    const unsigned char allowed_list[] = LOWALPHA HIALPHA DIGIT "!#$%&'*+-=?^_`{|}~@.[]";
    filter_map     map;

    filter_map_init(&map);
    filter_map_update(&map, 1, allowed_list);
    filter_map_apply(value, &map);
}    

Source for FILTER_VALIDATE_EMAIL:

void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
{
const char regexp[] = "/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/iD";

pcre       *re = NULL;
pcre_extra *pcre_extra = NULL;
int preg_options = 0;
int         ovector[150]; /* Needs to be a multiple of 3 */
int         matches;


/* The maximum length of an e-mail address is 320 octets, per RFC 2821. */
if (Z_STRLEN_P(value) > 320) {
    RETURN_VALIDATION_FAILED
}

re = pcre_get_compiled_regex((char *)regexp, &pcre_extra, &preg_options TSRMLS_CC);
if (!re) {
    RETURN_VALIDATION_FAILED
}
matches = pcre_exec(re, NULL, Z_STRVAL_P(value), Z_STRLEN_P(value), 0, 0, ovector, 3);

/* 0 means that the vector is too small to hold all the captured substring offsets */
if (matches < 0) {
    RETURN_VALIDATION_FAILED
}

}
18
répondu jbrahy 2017-04-03 21:58:25

la" bonne " façon de procéder consiste à demander le courriel de l'utilisateur deux fois (ce qui est pratique courante/bonne pratique). Mais pour répondre à votre question, FILTER_SANITIZE_EMAIL n'est pas inutile. C'est un filtre qui nettoie les e-mails et il fait bien son travail.

Vous avez besoin de comprendre qu'un filtre valide renvoie true ou false alors qu'un filtre assainit modifie en fait la variable donnée. Les deux ne servir le même but.

5
répondu David Titarenco 2011-09-03 02:03:05

j'ai lu le même article et j'ai pensé la même chose: changer simplement une variable invalide n'est pas suffisant. Nous avons besoin de dire à l'utilisateur qu'il y avait un problème, au lieu de simplement l'ignorer. La solution, je pense, est de comparer l'original à la version aseptisée. C'est-à-dire: pour utiliser l'exemple w3schools, il suffit d'ajouter:

$cleanfield=filter_var($field, FILTER_SANITIZE_EMAIL);
if($cleanfield != $field){
return FALSE;
}
3
répondu TamaMcGlinn 2013-03-07 13:22:30

Ne pas réinventer la roue, laissez votre serveur de messagerie de faire le travail:la vérification/validation des courriels est une question trop complexe pour tout faire à la main. Par exemple: les courriels valides peuvent, en fait, contenir des espaces selon la RFC2822. Sans même mentionner IDN.

Échapper à tous de sortie pour être sûr de XSS. Échapper paramètres SQL comme d'habitude. Utilisez des requêtes préparées. Si vous échappez correctement toutes vos entrées et sorties, alors ce que vous enregistrez dans une base de données n'a pas d'importance, donc assainir ce type de données est inutile.

résultat:

  • vérifier les e-mails seulement pour l'exactitude de base,
  • utiliser FILTER_VALIDATE_EMAIL si vous avez d',
  • ne pas utiliser FILTER_SANITIZE_EMAIL pour l'utilisateur des données soumises.

(la Pensée, on peut noter que sur certaines anciennes versions de PHP FILTER_VALIDATE_EMAIL n'a pas fait son travail bien pour un site internet typique: il va vous dire que john@gmail est un email valide.)

1
répondu sanmai 2016-07-04 03:33:02