2012-08-14 17 views
8

Potresti consigliarmi come procedere per evitare email injection in PHP mail() senza perdere i dati del messaggio originale? Per esempio. se devo consentire all'utente di utilizzare \r\n, To, CC ecc., quindi non voglio eliminarli completamente dal messaggio - voglio ancora che vengano consegnati, ma senza aggiungere ulteriori intestazioni o in qualche modo consentire l'invio di posta elettronica.Prevenzione corretta dell'iniezione di posta in PHP

La maggior parte dei suggerimenti su Internet suggeriscono di eliminare completamente questi dati, ma non voglio farlo.

Sto inviando messaggi di testo semplice (non HTML) tramite la funzione PHP mail().

Che cosa consiglieresti?

+0

'A:' e 'CC:' sono intestazioni - non si può mantenere la funzionalità rimuovendole. Non sono sicuro di cosa stai chiedendo qui. Fornisci un esempio della tua idea iniziale e cercheremo di guidarti nella giusta direzione :-). – Matt

+0

Dove stai usando i dati forniti dall'utente? Solo nel corpo del messaggio? – FtDRbwLXw6

+0

@drrcknlsn I dati forniti dall'utente si trovano nel corpo del messaggio e nella e-mail del destinatario. – Atm

risposta

7

Per filtrare messaggi di posta elettronica validi per l'utilizzo in campo e-mail del destinatario, dare un'occhiata a filter_var():

$email = filter_var($_POST['recipient_email'], FILTER_VALIDATE_EMAIL); 

if ($email === FALSE) { 
    echo 'Invalid email'; 
    exit(1); 
} 

Questo farà in modo gli utenti forniscono solo singolari, e-mail validi, che si può poi passare alla mail() funzione. Per quanto ne so, non c'è modo di iniettare intestazioni attraverso il corpo del messaggio usando la funzione PHP mail(), in modo che i dati non abbiano bisogno di alcuna elaborazione speciale.

Aggiornamento:

Secondo the documentation for mail(), quando si sta parlando direttamente a un server SMTP, è necessario per evitare punti fermi nel corpo del messaggio:

$body = str_replace("\n.", "\n..", $body); 

Aggiornamento # 2:

Apparentemente, è anche possibile iniettare tramite il soggetto, ma poiché non c'è lo FILTER_VALIDATE_EMAIL_SUBJECT, è necessario farlo Il filtraggio da soli:

$subject = str_ireplace(array("\r", "\n", '%0A', '%0D'), '', $_POST['subject']); 
+0

Grazie, ma su Internet si dice che è possibile iniettare intestazioni nel corpo del messaggio usando la funzione mail(). – Atm

+0

Tuttavia, grazie per la funzione filter_var. Lo userò invece dell'espressione regolare che sto usando. – Atm

+2

@Atern Nota filter_var ha alcune limitazioni su quali e-mail consente, ed è per questo che uso ancora regex per la convalida della posta elettronica, io uso: http://www.dominicsayers.com/isemail – Sammaye

3

si supponga di voler inserire l'indirizzo email del visitatore nel campo di intestazione opzionale in questo modo:

$headers = "From: $visitorEmailAddress"; 

Tuttavia, se

$ visitorEmailAddress

contiene

"[email protected] \ n \ nBCC: [email protected]"

ti sei fatto una serie di spam, aprendo la porta per l'iniezione elettronica. Questo è un esempio molto semplice, ma gli spammer creativi e gli hacker malintenzionati possono inserire degli script potenzialmente dannosi nella tua email, dato che l'e-mail viene inviata come un file di testo in chiaro. Anche gli allegati sono convertiti in testo semplice e possono facilmente inviare allegati aggiungendo una riga di contenuto del tipo di imminente.

Se la convalida del modulo per i campi FROM e/o TO è OK, è necessario esaminare la convalida del modulo per il corpo dell'e-mail.Spoglio i caratteri '- =' e '= -' e impedisco agli utenti di digitare codice HTML semplice usando strip_tags().

0

utilizzare una libreria mimo e-mail designato, come Mail_Mime:

<?php 
include 'Mail.php'; 
include 'Mail/mime.php' ; 

$mime = new Mail_mime(); 

$mime->setTXTBody("Message goes here"); 
$hdrs = $mime->headers(array(
    'From' => '[email protected]', 
    'Subject' => 'Test mime message' 
)); 
$body = $mime->get(); 

$mail = &Mail::factory('mail'); 
$mail->send('[email protected]', $hdrs, $body); 

?>