
  


---
title: "Evitar el Spam en el email con Honeypots - Carlos Sánchez"
description: "Un honeypot es una herramienta de seguridad que actúa como trampa para detectar, desviar o, en algunos casos, contrarrestar intentos de acceso no autorizado a los sistemas de información."
author: "Carlos Sánchez"
url: https://carlossanchezdonate.com/curiosidades/spam-email-honeypots/
image: https://carlossanchezdonate.com/wp-content/uploads/tb-honeypot.jpg
---





# 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](https://carlossanchezdonate.com/wp-content/uploads/cover-honeypot.jpg)




**Autor:**

        : [Carlos Sánchez](https://carlossanchezdonate.com/sobre-mi/)





**Fecha de publicación:**

        : 2024-06-24



**Última revisión:**

        : 2026-03-02




        **Índice**
                mostrar


        1
                ¿Qué es un honeypot?
        2
                Cómo hacer un Honeypot
        2.1
                Ajuste de JavaScript
        2.2
                Ajuste de PHP
        2.3
                Utilicemos nuestros conocimientos SEO de Renderizado a nuestro favor
        3
                Honeypot dinámico
        3.1
                Cómo implementarlo
        4
                Validación por tiempo
        4.1
                Implementar detección de envíos instantáneos
        5
                Detectar texto aleatorio de bots
        5.1
                Patrones sospechosos
        5.2
                Implementación en PHP
        6
                Combinando todas las capas
        7
                Impedir Spam en Contact Form 7
        7.1
                Crear el campo honeypot en Contact Form 7
        7.2
                Plugin completo con todas las capas
        7.3
                Usar el shortcode con honeypot incluido
        7.4
                En tu página de WordPress, añade:
        7.5
                Validación adicional del lado del servidor
        8
                Conclusión

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.

Así que hoy sin molestar al usuario con captchas, sin dependencias externas, y sin cargar scripts de terceros en toda la web te voy a explicar como configurar un sistema de seguridad para impedir que te lleguen los pesados correos de Spam con:

1. **Honeypot clásico**: Primer filtro para bots básicos.
2. **Honeypot dinámico**: Segundo filtro para bots que aprenden.
3. **Validación por tiempo**: Tercer filtro para bots rápidos.
4. **Detección de patrones**: Cuarto filtro para texto generado.
5. **Cookie de spam**: Bloqueo persistente de reincidentes.

## ¿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](https://carlossanchezdonate.com/wp-content/uploads/campo-oculto-honeypot.webp)

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:

``

Es muy importante poner el atributo de [autocomplete="nope"](https://www.w3schools.com/tags/att_input_autocomplete.asp) (o cualquier valor no estándar) para evitar que se ponga información automática de un usuario por error cuando esté completando el formulario. Uso "nope" en lugar de "off" porque algunos navegadores ignoran "off" en campos con nombres comunes como "firstname".

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](https://carlossanchezdonate.com/articulo/css-posicionamiento-web/) por medio de algún atributo.

Ejemplo:

`[name="firstname"] {

/* Mejor que display:none - más difícil de detectar */

position: absolute;

left: -9999px;

width: 1px;

height: 1px;

overflow: hidden;

}`

Con esta técnica el campo sigue existiendo en el DOM (los bots lo ven), pero está fuera de la pantalla. Un display:none es más fácil de detectar programáticamente.

### Ajuste de JavaScript

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

`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

// Lógica para establecer la cookie

setCookie('usuarioSpam', '1', 30); // Establece la cookie por 30 días

location.reload();

}

});

});`

`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 contiene el input

if (firstnameInput) {

if (firstnameInput.value.trim() !== "") {

event.preventDefault(); // Previene el envío del formulario

// Establece la cookie usuarioSpam

setCookie('usuarioSpam', '1', 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'])) {

setcookie("usuarioSpam", "1", time() + (86400 * 30), "/"); // Marca por 30 días

echo 'window.location.href="pagina_error.php";';

exit;

}`

### Utilicemos nuestros conocimientos SEO de Renderizado a nuestro favor

Como 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:

`Enviar Mensaje`

Este botón no hace nada por defecto, pero podemos convertirlo en un botón enviable gracias a JS:

`document.addEventListener('DOMContentLoaded', function() {

// Selecciona el botón y cambia su tipo a submit

const submitBtn = document.getElementById('submit-form');

if (submitBtn) {

submitBtn.type = 'submit';

}

});`

## Honeypot dinámico

El honeypot clásico tiene un problema: si un bot está programado específicamente para tu web, puede aprender que el campo "firstname" es trampa y simplemente no rellenarlo.

La solución es darle una vuelta de tuerca y que el nombre del campo cambie en cada carga de página. Un bot no puede aprender algo que nunca es igual.

En lugar de tener siempre un campo llamado "firstname", generamos un nombre aleatorio en el servidor y lo guardamos en sesión para poder verificarlo después:

`// En PHP, al generar el formulario:

session_start();

// Generar nombre único para este honeypot

$honeypot_name = 'hp_' . substr(md5(time() . rand()), 0, 8);

$_SESSION['honeypot_field'] = $honeypot_name;`

Cada vez que alguien carga el formulario, el campo honeypot tiene un nombre diferente: hp_a3f8b2c1, hp_7d2e9f4a, hp_c8b3a1d6...

### Cómo implementarlo

En el HTML del formulario:

`



[name=""] {

position: absolute;

left: -9999px;

width: 1px;

height: 1px;

}
