2011-09-03 9 views
17

Sto semplicemente creando un modulo di registrazione e sto cercando di inserire solo e-mail valide e sicure nel database.php - è FILTER_SANITIZE_EMAIL inutile?

Diversi siti (tra cui w3schools) ha raccomandato l'esecuzione FILTER_SANITIZE_EMAIL prima di eseguire FILTER_VALIDATE_EMAIL per essere sicuri, ma questo potrebbe cambiare l'e-mail inviata da un non valido in una e-mail valido, che non poteva essere ciò che l'utente ha voluto, per esempio:

utente ha e-mail [email protected], ma inserisce accidentalmente Jeff "@ gmail.com.

FILTER_SANITIZE_EMAIL sarebbe rimuovere il" rendendo l'e-mail che [email protected] FILTER_VALIDATE_EMAIL direbbe è valida anche se non è gli utenti indirizzo email attuale

Per evitare questo problema, ho intenzione di eseguire solo FILTER_VALIDATE_EMAIL. (supponendo che non abbia intenzione di generare/elaborare le email dichiarate non valide)

Questo mi dirà se l'e-mail è valida, se è quindi non ci dovrebbe essere bisogno di passarlo attraverso FILTER_SANITIZE_EMAIL perché qualsiasi illegale/caratteri non sicuri, avrebbe già causato la restituzione dell'e-mail non valida, corretta?

Inoltre, non conosco alcuna e-mail approvata come valida da FILTER_VALIDATE_EMAIL che potrebbe essere utilizzata per l'injection/xss a causa del fatto che spazi bianchi, parentesi() e punto e virgola invaliderebbero l'e-mail. O mi sbaglio?

(nota: Userò istruzioni preparate per inserire i dati in aggiunta a questo, volevo solo chiarire questo)

+0

tag SQL-injection rimosso –

+0

Quindi, tutte le risposte di seguito ha effettivamente dimostrato FILTER_SANITIZE_EMAIL è davvero inutile, perché possiamo semplicemente usare FILTER_VALIDATE_EMAIL solo. –

risposta

4

Il modo "corretto" di fare questo sta chiedendo di posta elettronica dell'utente due volte (che è comune/buona pratica). Ma per rispondere alla tua domanda, FILTER_SANITIZE_EMAIL non è inutile. È un filtro che disinfetta le email e fa bene il suo lavoro.

è necessario capire che un filtro che validates sia restituisce true o false mentre un filtro che sanitizes modifica in realtà la variabile data. I due fanno non servono allo stesso scopo.

+2

'I due non hanno lo stesso scopo. Che è esattamente quello che è stato affermato in parte della domanda. Questo non affronta ciò che viene chiesto. – Izkata

1

Non reinventare la ruota, lascia che il tuo server di posta faccia il lavoro: corretto email verification/validation is too complex matter per fare tutto a mano. Per esempio. le e-mail valide possono, infatti, contenere spazi come da RFC2822. Nemmeno menzionando IDN.

Fuggi tutte le uscite per essere sicuri di XSS. Esudi i parametri SQL come al solito. Utilizza query preparate. Se sfuggi correttamente tutti i tuoi input e output, allora non importa ciò che salvi in ​​un database, quindi sanificare questo tipo di dati è inutile.

Bottom line:

  • messaggi di posta elettronica di controllo solo per correttezza di base,
  • uso FILTER_VALIDATE_EMAIL se si deve,
  • non usano FILTER_SANITIZE_EMAIL per i dati inviati dagli utenti.

(pensato che potrebbe pena notare che in alcune vecchie versioni di PHP FILTER_VALIDATE_EMAIL non ha fatto bene il suo lavoro per un tipico sito Internet: esso vi dirà che [email protected] è un indirizzo email valido.)

+1

Ma 'john @ gmail' è un indirizzo email valido (gmail potrebbe essere un nome macchina localmente noto). Allo stesso modo 'john @ gmail.com' non è valido (gli spazi devono essere citati). Quindi il filtro è corretto su entrambi. – qbert220

+1

In effetti è valido, ma non si dovrebbe accettare la seguente email in un modulo di registrazione di un sito Web per ovvi motivi. – sanmai

+0

Sono d'accordo che accettare john @ gmail non è probabilmente auspicabile su un sito internet. Tuttavia, potrebbe essere perfettamente accettabile su un sito Web intranet. Nella tua risposta sembra implicare che il comportamento di FILTER_VALIDATE_EMAIL non sia corretto. IMO per i 2 casi a cui viene restituito il risultato corretto. Tuttavia, se il tuo uso particolare (ad esempio richiedendo un indirizzo email Internet globale) è diverso, potresti voler effettuare ulteriori verifiche (ad esempio, controllare un "." Nella parte che segue "@"). – qbert220

2

Ho letto lo stesso articolo e ho pensato la stessa cosa: cambiare semplicemente una variabile non valida non è sufficiente. Dobbiamo effettivamente dire all'utente che c'è stato un problema, invece di ignorarlo. La soluzione, penso, è di confrontare l'originale con la versione sterilizzata. Cioè per usare l'esempio W3Schools, basta aggiungere:

$cleanfield=filter_var($field, FILTER_SANITIZE_EMAIL); 
if($cleanfield != $field){ 
return FALSE; 
} 
17

Ecco come inserire le email solo validi.

<?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 e FILTER_SANITIZE_EMAIL sono entrambe le funzioni di valore e hanno diversi usi.

La convalida sta verificando se l'e-mail è un formato valido. Sanitizzare è eliminare i caratteri non validi dall'e-mail.

<?php 
$email = "[email protected]"; 
$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 = "[email protected]"; 
$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 è open source, quindi è facile rispondere a queste domande semplicemente usandolo.

Source for 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 "!#$%&'*+-=?^_`{|}[email protected][]"; 
    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 
} 

} 
+5

'La verifica sta verificando se l'e-mail è un formato valido. Sanificare è pulire i cattivi personaggi dall'email. 'Questo è stato affermato in parte della domanda. Questa risposta non affronta ciò che viene chiesto. – Izkata

+1

ok, abbastanza giusto @Izkata. Risposta aggiornata in modo che possa inserire solo e-mail valide. – jbrahy

+2

Puoi per favore mostrare un esempio che mostri chiaramente come l'e-mail di sanificazione passerà insieme a una convalida? Sembra che il tuo primo blocco faccia passare l'e-mail SOLO SE non può essere disinfettato, o mi sono perso qualcosa di ovvio? E se è così, perché sterilizzare in primo luogo? Sembra ridondante. – BlackBeltScripting

Problemi correlati