Correo electrónico seguro en PHP

En el script de correo electrónico PHP del capítulo anterior, hay una vulnerabilidad.

Inyección de E-mail PHP

Primero, vea el código PHP del capítulo anterior:

<html>
<body>
<?php
if (isset($_REQUEST['email']))
//si se rellena "email", enviar correo electrónico
  {
  //enviar correo electrónico
  $email = $_REQUEST['email']; 
  $subject = $_REQUEST['subject'];
  $message = $_REQUEST['message'];
  mail("someone@example.com", "Asunto: $subject",
  $message, "From: $email" );
  echo "Gracias por usar nuestro formulario de correo";
  }
else
//si no se rellena "email", muestra el formulario
  {
  echo "<form method='post' action='mailform.php'>
  Correo electrónico: <input name='email' type='text' /><br />
  Asunto: <input name='subject' type='text' /><br />
  Mensaje:<br />
  <textarea name='message' rows='15' cols='40'>
  </textarea><br />
  <input type='submit' />
  </form>";
  }
?>
</body>
</html>

El problema con el código anterior es que los usuarios no autorizados pueden insertar datos en la cabecera del correo mediante el formulario.

¿Qué sucederá si el usuario ingresa estos textos en los cuadros de texto del formulario?

someone@example.com%0ACc:person2@example.com
%0ABcc:person3@example.com,person3@example.com,
anotherperson4@example.com,person5@example.com
%0ABTo:person6@example.com

Como de costumbre, la función mail() coloca el texto superior en la cabecera del correo, por lo que ahora la cabecera tiene campos adicionales Cc:, Bcc: y To:. ¡Cuando el usuario haga clic en el botón de enviar, este correo electrónico se enviará a todas las direcciones enumeradas anteriormente!

PHP para evitar inyecciones de correo electrónico

La mejor manera de evitar inyecciones de correo electrónico es validar la entrada.

El siguiente código es similar al del capítulo anterior, pero hemos añadido un programa de validación de entrada para el campo email del formulario:

<html>
<body>
<?php
function spamcheck($field)
  {
  //filter_var() limpia el correo electrónico 
  //usar FILTER_SANITIZE_EMAIL para la dirección
  $field=filter_var($field, FILTER_SANITIZE_EMAIL);
  //filter_var() valida el correo electrónico
  //usar FILTER_VALIDATE_EMAIL para la dirección
  if(filter_var($field, FILTER_VALIDATE_EMAIL))
    {
    return TRUE;
    }
  else
    {
    return FALSE;
    }
  }
if (isset($_REQUEST['email']))
  //si "correo electrónico" está rellenado, proceder
  //verificar si la dirección de correo electrónico es inválida
  $mailcheck = spamcheck($_REQUEST['email']);
  if ($mailcheck==FALSE)
    {
    echo "Entrada inválida";
    }
  else
    //enviar correo electrónico
    $email = $_REQUEST['email']; 
    $subject = $_REQUEST['subject'];
    $message = $_REQUEST['message'];
    mail("someone@example.com", "Asunto: $subject",
    $message, "From: $email" );
    echo "Gracias por usar nuestro formulario de correo";
    }
  }
else
  {//si "email" no está lleno, muestra el formulario
  echo "<form method='post' action='mailform.php'>
  Correo electrónico: <input name='email' type='text' /><br />
  Asunto: <input name='subject' type='text' /><br />
  Mensaje:<br />
  <textarea name='message' rows='15' cols='40'>
  </textarea><br />
  <input type='submit' />
  </form>";
  }
?>
</body>
</html>

En el código anterior, usamos los filtros de PHP para validar la entrada:

  • FILTER_SANITIZE_EMAIL para eliminar caracteres ilegales de la dirección de correo electrónico
  • FILTER_VALIDATE_EMAIL para verificar la dirección de correo electrónico

Puede encontrar más información en nuestra Filtros de PHPLea más sobre los filtros en esta sección.