18 de Octubre
PLAZAS LIMITADAS

Combatir el Spam de correos con Honeypots

Los honeypots representan una técnica de defensa que, aunque simple, es extremadamente efectiva en la distinción entre usuarios legítimos y bots maliciosos.

Combatir el Spam de correos con Honeypots
Autor:
Carlos Sánchez
Fecha de publicación:
2024-06-24

Última revisión:
2024-06-24

Aunque esto salga del área de SEO. Que un cliente reciba Spam de forma masiva en su correo por medio del formulario de contacto podría afectar a nuestros leads. Por no hablar que en el caso de que se haga de forma masiva, acabará consumiendo muchos recursos de nuestro servidor y por tanto ralentizando nuestra web.

Para esto existen distintas medidas de control. Algunas que son especialmente invasivas con el usuario y puede afectar a la finalización de ese lead. Es decir, si un usuario se frustra porque no puede resolver un captcha complejo, es posible que al final decida no enviar dicho formulario.

Para esto existen trucos como el Honeypot, que es una forma no invasiva de evitar el envío de formulario por parte de un bot. De hecho es la mecánica menos intrusiva.

reCaptcha v3 lo que hace es que monitorea el comportamiento del usuario en todo el sitio web (teniendo que cargar el js por toda la web para que sea efectivo), le asigna un puntaje y en base a eso decide si se puede enviar el formulario o no.

Un Honeypot bien hecho es más simple pero no por ello menos efectivo. De hecho son prácticas combinables y pueden ser usadas complementariamente para fortalecer la seguridad de un sitio web.

¿Qué es un honeypot?

Un Honeypot es una estrategia de seguridad de dejar un campo invisible para los usuarios reales, pero que los bots no se pueden contener el ansia por rellenar dicho campo. Los bots tienden a rellenar todos los campos para enviar un formulario de contacto a fin de poder mandar su spam. Cuando nosotros detectamos que dicho campo contiene información, ¡PUM! Bot invalidado.

Campo oculto de honeypot

La idea es que sea irresistible para los bots y que de esta forma al recibir nosotros información con ese campo lleno, sepamos y tengamos claro que quien nos está enviando información es un bot y no una persona real. Pues una persona real no va a desvelar dicho campo para rellenarlo.

Hay muchas formas de implementar un Honeypot, yo os voy a explicar cómo lo hago yo que es bastante eficiente y me ha funcionado bien, pero esta implementación se puede complementar y mejorar de muchas formas.

Cómo hacer un Honeypot

En primer lugar tenemos que crear un campo atractivo, pero que el usuario no pueda rellenar por error. Mi sugerencia es no ponerle un type="hidden" o un display:none; de forma inline en el propio HTML. Pues un bot puede estar programado de forma muy sencilla para ver y detectar ese campo y de esta forma no completarlo.

Cuando el bot llene la información, le añadiremos una cookie llamada "usuarioSpam" por ejemplo. Y lo podemos hacer con los siguientes pasos, empezando por crear el campo invisible:

Ejemplo:

<input type="text" name="firstname" id="calle" class="form-control sib-NAME-area" placeholder="direccion" autocomplete="off">

Es muy importante poner el atributo de autocomplete="off" para evitar que se ponga información automática de un usuario por error cuando esté completando el formulario. El valor de este atributo se podría cambiar con JS si lo deseamos para hacerlo más difícil de detectar para un bot.

En mi experiencia, con el type="hidden" muchos bots se evitan rellenar esa información. Aunque sea la forma nativa de HTML de ocultar un campo, mi recomendación es ocultarlo con CSS por medio de algún atributo.

Ejemplo:

[name="firstname"] {
display: none;
}

Ese display none lo añado sabiendo que no voy a poner ese atributo en ningún otro campo. En contra de lo que te dirá ChatGPT y los estándars de HTML sí, utilizaré un atributo estandarizado para hacerlo más atractivo para el bot. Y evitamos que se llene de forma automática con el autocomplete off.

Ajuste de JavaScript

Si alguien hace click o le da para rellenar la información de nuestro elemento oculto, le insertamos la coockie:

document.addEventListener('DOMContentLoaded', function() {
document.querySelector('.sib-default-btn').addEventListener('click', function(event) {
var firstnameInput = document.querySelector('input[name="firstname"]');
if (firstnameInput && firstnameInput.value.trim() !== "") {
// Previene la acción por defecto si es necesario
event.preventDefault(); // Comentar si no quieres bloquear el envío para asegurarte de bloquear más intentos del bot
// Lógica para establecer la cookie
setCookie('usuarioSpam', 'active', 30); // Establece la cookie por 30 días
// Mensaje de alerta para el usuario
location.reload();
// Si deseas permitir que el formulario continúe su envío normal, no uses preventDefault()
// y asegúrate de que el establecimiento de la cookie y cualquier otra lógica se complete rápidamente.
}
});
});

document.addEventListener('DOMContentLoaded', function() {
document.body.addEventListener('submit', function(event) {
var form = event.target;
var firstnameInput = form.querySelector('input[name="firstname"]');
// Asegurarse de que el formulario incluido en la delegación contiene un input name="firstname"
if (firstnameInput) {
if (firstnameInput.value.trim() !== "") {
event.preventDefault(); // Previene el envío del formulario
// Establece la cookie usuarioSpam
setCookie('usuarioSpam', 'active', 30); // Establece la cookie por 30 días
location.reload();
}
}
}, true);
});

Establecemos la función setCookie:

function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}

Ajuste de PHP

En el php para el envío de correo, donde se verifican los errores y miramos la seguridad:

Este código en un encabezado de toda la web para asegurarnos que si tiene una cookie de bot, no pueda acceder a la web:

if(isset($_COOKIE["usuarioSpam"]) && $_COOKIE["usuarioSpam"] == "1") {
// Manejar el intento como spam
die("Tu solicitud ha sido identificada como spam.");
}

Y esto para añadirle la cookie en caso de que el bot consiga enviar el formulario:

if (isset($_POST['firstname']) && !empty($_POST['firstname'])) {
// Enviar el código de estado 403
// Marcar al usuario como spam
$urlActual = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
setcookie("usuarioSpam", "1", time() + (86400 * 30), "/"); // Marca por 30 días
echo '<script>window.location.href="pagina_error.php";</script>''; // Creamos la página de error con el código correspondiente
header("Location: $urlActual");
exit;
}

Ajuste de seguridad extra

Podemos garantizarnos que sólo se envíe el formulario cuando el usuario tenga JavaScript de una forma muy simple. El botón de enviar podemos hacer que solo funcione con JavaScript con un ajuste sencillo. Haciendo que JS modifique el DOM para que sea un botón de enviar real:

<button type="testbot" class="cta" style="background: var(--secondary);" id="submit-form">Enviar Mensaje</button>

Como puedes observar, esto no es ningún type="submit", pero podemos convertirlo en un botón enviable gracias a JS:

document.addEventListener('DOMContentLoaded', function() {
// Selecciona todos los elementos input con type="testbot"
const inputs = document.querySelectorAll('input[type="testbot"]');
// Actua sobre cada elemento input de estas características encontrado y cambia su type a "submit"
inputs.forEach(function(input) {
input.type = 'submit';
});
});

Impedir Spam en contact form 7

En el caso de que en el formulario de contacto estés empleando el famoso plugin contact form 7, vamos a ver como implementar el honeypotcon los mismos pasos.

RECUERDA: Nunca debes probar códigos de terceros de forma directa en un entorno en producción, ni siquiera los míos. Por cualquier motivo, ya sea error humano o incompatibilidades, un código puede romper la web. Asegúrate de probarlo primero en un entorno seguro.

Crear el campo honeypot en contact form 7

Primero, necesitamos añadir un campo que actuará como honeypot. Este campo será visible para los bots pero invisible para los usuarios humanos, usando CSS para ocultarlo efectivamente.

[[text* firstname id:firstname class:form-control sib-NAME-area placeholder="direccion" autocomplete="off"]]

Este campo, aunque no es de tipo hidden, será ocultado usando CSS. Lo designamos con un placeholder inofensivo como "dirección" para engañar a los bots.

Ocultar el Campo con CSS en el Shortcode Personalizado

Para asegurarnos de que este campo solo se oculte cuando se utilice el formulario, incorporaremos el CSS necesario dentro del shortcode que envuelve el formulario de Contact Form 7.

Modifica el shortcode personalizado en functions.php:


function custom_contact_form_shortcode($atts) {
$atts = shortcode_atts(array(
'id' => '',
), $atts);
$output = '';
// Añade el CSS para ocultar el campo honeypot
$css = '<style>
#firstname {
display: none;
}
</style>'
;
// Incluye el formulario de Contact Form 7
if (!empty($atts['id'])) {
$output .= $css;
$output .= do_shortcode('[contact-form-7 id="' . esc_attr($atts['id']) . ']');
}
return $output;
}
add_shortcode('custom_contact_form', 'custom_contact_form_shortcode');

Usar el Shortcode Personalizado

Para utilizar el formulario con el honeypot incorporado, coloca el shortcode personalizado en la página donde deseas mostrar el formulario.

En tu página de WordPress, añade:

[[custom_contact_form id="ID_del_formulario"]]


Reemplaza "ID_del_formulario" con el ID real de tu formulario de Contact Form 7.

Explicación Adicional y Mejoras de Seguridad

Al utilizar este método, aseguramos que el campo honeypot solo esté oculto en las páginas que realmente contienen el formulario, evitando modificar globalmente el comportamiento del sitio y mejorando el rendimiento. Además, este enfoque evita que los usuarios humanos interactúen accidentalmente con el campo oculto, mientras que los bots que no ejecutan JavaScript o que no respetan los estilos CSS seguirán llenándolo, revelando su naturaleza no humana.

Validación del lado del servidor en PHP

No olvides que también es importante manejar la validación del lado del servidor. Si detectas que el campo honeypot está lleno cuando se envía el formulario, debes bloquear esa solicitud ya que es indicativo de actividad de bot.

Añade a functions.php para manejar la validación:

function check_honeypot_field() {
if (!empty($_POST['firstname'])) {
wp_die('Error: Se detectó actividad de spam.');
}
}
add_action('init', 'check_honeypot_field');

Este script de PHP intercepta las peticiones antes de que WordPress las procese completamente, verificando si el campo honeypot está lleno y, en caso afirmativo, termina la ejecución y devuelve un mensaje de error.

Esta sería la forma simple de implementar dicho honeypot en contact form 7.

Si te gusta este artículo, me ayudarías un montón compartiendo mi contenido:
No se te da mal el SEO Técnico

Te falta mi máster. Accede a una formación avanzada que te permitirá aplicar e implementar SEO en cualquier tipo de WEB

¡Accede al Máster de SEO Técnico!
Tal vez te interesen otros artículos:
Artículos de SEO

Si te ha gustado esta publicación, siempre me lo puedes agradecer dándome like en esta publicación de LinkedIn sobre este mismo artículo.

Usamos cookies para asegurar que te damos la mejor experiencia en nuestra web. Aquí tienes nuestra política de privacidad.