2012-08-14 10 views
8

¿Podría aconsejarme cómo hago para evitar email injection en PHP mail() sin perder los datos del mensaje original? P.ej. si necesito permitir que el usuario use \r\n, To, CC etc., así que no quiero desvincularlos por completo del mensaje; aún así quiero que se entreguen, pero sin agregar encabezados adicionales ni permitir de algún modo la inyección de correo.Prevención adecuada de inyección de correo en PHP

La mayoría de los consejos en Internet sugieren eliminar por completo esos datos, pero no quiero hacerlo.

Envío de mensajes de texto sin formato (HTML) a través de la función PHP mail().

¿Qué aconsejarías?

+0

'Para:' y 'CC:' son cabeceras - no se puede mantener la funcionalidad mediante la eliminación de ellos. No estoy seguro de lo que estás preguntando aquí. Proporcione una muestra de su idea inicial y trataremos de guiarlo en la dirección correcta :-). – Matt

+0

¿Dónde está utilizando los datos proporcionados por el usuario? ¿Solo en el cuerpo del mensaje? – FtDRbwLXw6

+0

@drrcknlsn Los datos proporcionados por el usuario se encuentran en el cuerpo del mensaje y en el correo electrónico del destinatario. – Atm

Respuesta

7

Para filtrar mensajes de correo electrónico válidas para su uso en el campo de correo electrónico del destinatario, echar un vistazo a filter_var():

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

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

Esto hará que sus usuarios facilitan sólo, correos electrónicos válidos singulares, que luego se puede pasar a la mail() función. Por lo que yo sé, no hay forma de inyectar encabezados a través del cuerpo del mensaje usando la función PHP mail(), por lo que los datos no necesitan ningún procesamiento especial.

Actualización:

Según the documentation for mail(), cuando se está hablando directamente a un servidor SMTP, necesitará para evitar puntos y aparte en el cuerpo del mensaje:

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

Actualización # 2:

Aparentemente, también es posible inyectar a través del sujeto, pero como no existe FILTER_VALIDATE_EMAIL_SUBJECT, deberá hacer el mismo filtrado:

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

Gracias, pero en Internet dice que es posible inyectar encabezados en el cuerpo del mensaje usando la función mail(). – Atm

+0

Sin embargo, gracias por la función filter_var. Voy a usarlo en lugar de la expresión regular que estoy usando. – Atm

+2

@Atern Nota filter_var tiene algunas limitaciones sobre los correos electrónicos que permite, por eso sigo usando regex para la validación de correo electrónico, yo uso: http://www.dominicsayers.com/isemail – Sammaye

3

que suponga que desea poner la dirección de correo electrónico del visitante en el campo de cabecera opcional de este modo:

$headers = "From: $visitorEmailAddress"; 

Sin embargo, si

$ visitorEmailAddress

contiene

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

te has convertido en una gran cantidad de spam, abriendo la puerta para la inyección electrónico. Este es un ejemplo muy simple, pero los creadores de spam creativos y hackers malintencionados pueden introducir scripts potencialmente dañinos en su correo electrónico, ya que el correo electrónico se envía como un archivo de texto plano. Incluso los archivos adjuntos son textos sin formato convertidos, y pueden enviar fácilmente adjuntos agregando una línea de contenido de tipo mimético.

Si la validación de formulario para los campos FROM y/o TO es correcta, debe consultar la validación de formulario para el cuerpo del correo electrónico.Quitaría los caracteres '- =' y '= -', y evitaría que los usuarios escriban HTML sin formato usando strip_tags().

0

utilizar una biblioteca de correo electrónico MIME designado, como 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); 

?> 
Cuestiones relacionadas