Bloqueá scanners en PHP sin Redis ni base de datos
Cada día, bots automatizados escanean tu servidor PHP buscando archivos expuestos, paneles de administración sin protección e inyecciones SQL. Sin rate limiting ni detección de firmas, estas herramientas generan miles de solicitudes por minuto, consumen ancho de banda y saturan tus logs, aunque tu app no tenga ninguna vulnerabilidad real. La solución existe y no necesitás Redis, una base de datos ni servicios externos.
En 30 segundos
- Herramientas como Nikto, Nmap, sqlmap y Masscan escanean millones de servidores cada día buscando rutas sensibles como
/wp-admin,.envy.git - El rate limiting con ventana deslizante es la defensa más simple: bloqueás al IP que supera N solicitudes en X segundos, devolviendo HTTP 429
- La librería xZeroProtect implementa esto en PHP 8 sin Redis ni base de datos, instalable con Composer en dos líneas
- La detección por User-Agent firma herramientas conocidas (sqlmap, nikto, acunetix, feroxbuster) pero tiene límites: bots sofisticados falsifican User-Agents
- Googlebot y Bingbot se verifican con DNS doble inverso, no bloqueés crawlers legítimos o perdés posicionamiento
¿Qué son los scanners web y por qué afectan tu aplicación PHP?
Un scanner web es un programa automatizado que recorre internet buscando servidores vulnerables. Algunos son legítimos: Shodan y Censys mapean servicios públicos con fines de investigación. Pero la mayoría de los que van a golpear tu app PHP no tienen esos fines.
Según el artículo de referencia publicado el 16 de mayo de 2026, estos bots envían miles de solicitudes por minuto, no porque te estén apuntando específicamente, sino porque escanear todo internet es barato y fácil. Prueban rutas en masa, inyectan payloads genéricos y pasan al siguiente IP si no encuentran nada.
El impacto es real incluso si tu app no tiene bugs: logs inflados con miles de entradas basura, consumo de CPU y ancho de banda que vos pagás, y en algunos casos ralentización real de usuarios legítimos durante picos de escaneo.
La pregunta que se hace todo el mundo: ¿no debería manejarlo Nginx o Apache? Sí y no. Podés escribir reglas de firewall, pero requieren conocimiento específico, mantenimiento y acceso al servidor. A nivel PHP tenés control sobre la lógica de cada request sin depender de la capa de infraestructura, lo que sirve especialmente en hosting compartido o cuando no tenés acceso root.
Herramientas de escaneo: Nikto, Nmap, sqlmap y las que usás sin saber que existían
Estas herramientas son de código abierto, están activamente mantenidas y cualquiera las descarga gratis. No son armas de estado, son el equivalente de un destornillador en el mundo de la seguridad ofensiva.
Nikto
Escanea servidores web en busca de más de 6.700 archivos y configuraciones peligrosas conocidas. Detecta versiones de software vulnerables, cabeceras HTTP mal configuradas y archivos que nunca deberían estar expuestos. Su User-Agent característico incluye la cadena “Nikto” o variantes de ella, lo que facilita la detección.
Nmap y Masscan
Nmap escanea puertos abiertos y servicios corriendo. Masscan va más rápido: puede barrer rangos completos de IPs en segundos. Cuando tu servidor aparece con el puerto 80 o 443 abierto, queda en las listas de estos bots y empieza a recibir pruebas sistemáticas.
sqlmap, dirbuster, gobuster y similares
sqlmap automatiza la detección e inyección SQL. Manda cientos de variantes de payloads maliciosos a formularios, parámetros GET y cookies. Gobuster y dirbuster hacen fuerza bruta de rutas: prueban miles de paths posibles buscando uno que responda 200 en vez de 404. Feroxbuster y ffuf son versiones más rápidas de lo mismo. Hydra hace fuerza bruta sobre formularios de login.
Lo que tienen en común: todos dejan rastros en los logs, todos generan volumen de requests anormal y casi todos tienen User-Agents identificables en su configuración por defecto (aunque eso se puede cambiar). Esto se conecta con lo que analizamos en alternativas cuando descartamos una base de datos.
Patrones de ataque: qué rutas buscan y qué payloads tiran
Ponele que instalaste WordPress y dejás la URL de instalación por defecto. En minutos, bots están golpeando /wp-admin, /wp-login.php, /xmlrpc.php y /?author=1 para enumerar usuarios. No necesitan saber que usás WordPress: lo prueban en todos los servidores.
Las rutas más buscadas por estos scanners:
/wp-admin,/wp-login.php,/administrator— paneles CMS/phpmyadmin,/adminer.php— interfaces de base de datos/.env,/.git,/.htpasswd— archivos de configuración que nunca deberían ser públicos/backup.sql,/dump.sql,/db.bak— dumps de base de datos olvidados/config.php,/configuration.php,/settings.php— archivos de config expuestos
Los payloads que tiran en parámetros son igual de predecibles: UNION SELECT NULL-- para inyección SQL, <script>alert(1)</script> para XSS, ../../../etc/passwd para path traversal, system() y eval() para ejecución de código. Si tu app filtra correctamente estos inputs, no hay problema. El problema es cuando no filtra, y cuando el volumen de requests tira el servidor antes de que el atacante encuentre algo.
Rate limiting sin dependencias externas: la defensa más directa
El rate limiting es simple: si un IP hace más de N solicitudes en X segundos, lo bloqueás temporalmente y devolvés HTTP 429 (Too Many Requests). Sin Redis, sin base de datos, sin nada externo.
Hay dos algoritmos principales. Fixed window: contás requests en ventanas fijas de tiempo (por ejemplo, los últimos 60 segundos). Es simple pero tiene un problema: un atacante puede hacer el doble de requests en el borde de dos ventanas. Sliding window: la ventana se mueve con el tiempo, eliminando ese borde. Es más precisa y no es mucho más compleja de implementar en PHP.
La implementación más básica usa APCu (si está disponible) o el sistema de archivos para persistir contadores por IP. Sin estado externo, sin dependencias, solo PHP.
El resultado práctico: un bot que manda 500 requests por minuto buscando /.env recibe 429 después del request número 30 y pasa al siguiente IP. Vos eliminaste el ruido de 470 requests que habrían llegado a tu app.
xZeroProtect: implementación PHP sin Redis ni base de datos
La librería xZeroProtect para PHP 8 implementa exactamente esto. Instalación:
composer require webrium/xzeroprotect
Integración en index.php en dos líneas:
use Webrium\XZeroProtect\Shield;
Shield::init();
La configuración básica permite definir max_requests (límite por IP) y per_seconds (ventana de tiempo). Sin archivo de configuración externo, sin conexión a Redis, sin tabla en MySQL. La librería usa archivos temporales o APCu para los contadores.
¿Y qué pasó cuando lo probaron en producción? Los logs de prueba muestran que el ruido de bots se reduce drásticamente en los primeros minutos de activación. No es magia: es que la mayoría de estos bots no tienen lógica para reintentar con delay cuando reciben 429.
Detección por User-Agent: útil, pero no infalible
xZeroProtect incluye detección de firmas de herramientas conocidas. Si el User-Agent incluye “sqlmap”, “nikto”, “nessus”, “acunetix”, “masscan”, “dirbuster”, “gobuster”, “feroxbuster”, “wfuzz”, “ffuf”, “hydra” o “metasploit”, el request se bloquea antes de que llegue a tu lógica de negocio. Cubrimos ese tema en detalle en integrar validaciones de seguridad en CI/CD.
Eso sí: esto es la primera capa, no la única. Bots sofisticados falsifican User-Agents. Un atacante con algo de experiencia configura sqlmap para que se identifique como Chrome. La detección por firma captura el 80% del ruido automatizado, el que usan principiantes o bots masivos que ni se molestan en ocultar su origen. Para el otro 20%, necesitás rate limiting.
La combinación de ambas capas cubre la mayoría de los escenarios reales.
Protección de rutas sensibles en PHP
xZeroProtect bloquea automáticamente intentos de acceso a rutas sensibles conocidas. Pero si manejás rutas propias que no quieren ser públicas, podés agregar reglas personalizadas.
El patrón es el mismo: antes del routing de tu app, interceptás el request, verificás la ruta contra una lista negra y devolvés 403 o 404 sin procesar nada más. Esto es más eficiente que dejar que tu framework procese el request completo y luego devuelva error.
Para WordPress en particular (donde el volumen de ataques es alto), proteger /xmlrpc.php a nivel PHP o server reduce el ruido significativamente. Si tenés hosting en donweb.com, podés complementar esto con reglas en el panel de seguridad antes de que el request llegue a PHP.
Verificación de bots legítimos: Googlebot no es igual a un scanner
Acá viene lo bueno: si bloqueás demasiado agresivo, terminás bloqueando a Googlebot y perdés posicionamiento. Los bots de Google y Bing se pueden verificar con DNS doble inverso: resolvés el IP del request, verificás que el hostname sea googlebot.com o google.com, y después resolvés ese hostname de vuelta al IP original.
Si coincide, es legítimo. Si no coincide (incluso si el User-Agent dice “Googlebot”), es un impostor y lo tratás como cualquier bot sospechoso. Hay bots que falsifican el User-Agent de Google específicamente para evitar detección (sí, en serio).
xZeroProtect incluye whitelist configurable para crawlers verificados. La regla: permitir siempre crawlers verificados, no importa el volumen de requests, porque un Googlebot agresivo sigue siendo mejor que un Googlebot bloqueado.
Comparativa de métodos de defensa contra scanners en PHP
| Método | Dependencias | Dificultad | Efectividad | Falsos positivos |
|---|---|---|---|---|
| Rate limiting con archivos/APCu | Ninguna | Baja | Alta contra bots masivos | Bajo |
| Detección por User-Agent | Ninguna | Muy baja | Media (evitable) | Muy bajo |
| Blacklist de rutas sensibles | Ninguna | Muy baja | Alta para rutas conocidas | Ninguno |
| Rate limiting con Redis | Redis | Media | Muy alta | Bajo |
| WAF externo (Cloudflare, etc.) | Servicio externo | Baja | Muy alta | Medio |
| Reglas Nginx/Apache | Acceso servidor | Alta | Alta | Bajo |

Para proyectos pequeños y medianos sin acceso root ni presupuesto para servicios externos, la combinación de rate limiting con archivos + detección por User-Agent + blacklist de rutas cubre el 80-90% del ruido automatizado real.
Errores comunes al implementar protección contra scanners
Bloquear por User-Agent y asumir que es suficiente
El User-Agent es el parámetro más fácil de falsificar en una solicitud HTTP. Cualquiera que corra sqlmap con --user-agent="Mozilla/5.0" pasa el filtro. La detección por User-Agent es una primera capa de filtrado rápido, no una defensa completa. Siempre combinala con rate limiting.
Configurar el límite demasiado bajo y bloquear usuarios reales
Un límite de 10 requests por minuto suena estricto con los bots, pero si tenés una SPA que hace llamadas frecuentes a la API o usuarios que recargan la página varias veces seguidas, los vas a bloquear. Empezá con límites generosos (60-100 por minuto) y ajustá según tus logs. Observá primero, bloqueés después. Tema relacionado: escribir scripts ligeros de defensa.
No verificar bots legítimos antes de aplicar rate limiting
Googlebot puede hacer decenas de requests por minuto a tu sitio. Si aplicás rate limiting global sin whitelist de crawlers verificados, terminás con tu sitio mal indexado. La verificación DNS doble es obligatoria antes de activar restricciones agresivas.
Devolver 403 en vez de 404 o 429 para rutas sensibles
El 403 confirma que la ruta existe pero está protegida. Un 404 da menos información al atacante. Para rutas que nunca deberían existir públicamente (como /.env), devolver 404 es mejor práctica porque no confirma que el archivo esté ahí.
Preguntas Frecuentes
¿Cómo bloquear scanners automatizados en una aplicación PHP?
La combinación más efectiva sin dependencias externas es rate limiting (devolver HTTP 429 cuando un IP supera N requests en X segundos) más detección de User-Agents de herramientas conocidas. La librería xZeroProtect implementa ambas en PHP 8 con composer require webrium/xzeroprotect y dos líneas de código en tu entry point.
¿Puedo usar rate limiting en PHP sin Redis ni memcached?
Sí. Usando APCu (si está habilitado en tu servidor) o el sistema de archivos para persistir contadores por IP, el rate limiting funciona sin ninguna dependencia externa. APCu es más rápido porque opera en memoria, pero los archivos temporales zafan perfectamente para tráfico bajo o medio. xZeroProtect usa esta aproximación por defecto.
¿Qué herramientas de escaneo son las más comunes contra apps PHP?
Nikto (detecta 6.700+ rutas y configuraciones peligrosas), sqlmap (inyección SQL automatizada), gobuster y feroxbuster (fuerza bruta de rutas), Nmap (escaneo de puertos y servicios) y Masscan (velocidad extrema en rangos de IP). Todas son de código abierto, gratuitas y tienen User-Agents identificables en su configuración por defecto.
¿Cómo proteger WordPress de escaneos de vulnerabilidades?
Bloqueá o limitá el acceso a /xmlrpc.php, /wp-login.php y /wp-json/wp/v2/users (enumeración de usuarios). Aplicá rate limiting en el login. Bloqueá por User-Agent herramientas conocidas. Usá reglas en .htaccess para denegar acceso a archivos como .env, .git y wp-config.php.bak. Combinado con rate limiting en PHP, cubrís la mayoría de los ataques automatizados.
¿Cómo verificar que Googlebot es legítimo y no un impostor?
Con verificación DNS doble: resolvés el IP del request a nombre de host (reverse DNS), verificás que el hostname termine en googlebot.com o google.com, y luego resolvés ese hostname de vuelta al IP original. Si el IP coincide, es legítimo. Si no coincide, independientemente del User-Agent, es un bot que falsifica su identidad.
Conclusión
Escaneos automatizados llegan a todos los servidores, no solo a los grandes. El punto de esta nota es que no necesitás infraestructura cara para defenderte del ruido masivo: rate limiting bien configurado más detección de firmas cubre la mayoría de los casos sin Redis, sin WAF externo y sin tocar la configuración de Nginx.
xZeroProtect es una referencia concreta de que esto se puede implementar en PHP 8 con Composer en minutos. La combinación realista: activás la librería, configurás un límite conservador (60-80 requests por minuto), agregás whitelist para Googlebot con verificación DNS doble y revisás los logs la primera semana para ajustar. Después de eso, el ruido baja y tus logs vuelven a ser legibles.
¿Alguien necesita Redis para implementar esto bien? No para el 80% de los proyectos PHP medianos. Si estás en alto tráfico real, ahí sí Redis o un WAF externo dan más granularidad. Pero para empezar, el sistema de archivos alcanza.
Fuentes
- Dev.to — Stop Scanners from Hammering Your PHP App (artículo original, mayo 2026)
- GitHub — webrium/xzeroprotect (librería PHP sin dependencias externas)
- Marín de la Fuente — Escaneo de vulnerabilidades con Nikto
- Seguridad en WordPress — Protección DDoS y bots, guía 2026
- Medium — Implementación de rate limiter simple en PHP






