Respecto a CAPTCHA: Recomendaría no usar CAPTCHA a menos que realmente lo necesite. ¿Por qué?
- es feo.
- es molesto para sus usuarios. No debe hacer que salten por aros para usar su sitio.
hay algunas alternativas que son muy simples, pueden ser muy eficaces y son totalmente transparentes para (casi todos) usuarios.
campos Honeypot: añadir un campo a sus formas con un nombre común como "sitio web". A su lado, agregue una etiqueta que diga algo al efecto de "no escriba en esta casilla". Al usar Javascript, oculta la entrada y la etiqueta. Cuando recibe un envío de formulario, si hay algo en el campo, rechace la entrada.
Los usuarios con JS no lo verán y estarán bien. Los usuarios sin JS simplemente tendrán que seguir las instrucciones simples. Los Spambots se enamorarán y se revelarán a sí mismos.
Faux-CAPTCHA automático: Esto es similar a lo anterior. Agregue un campo de entrada con una etiqueta que diga "Write 'Alex'" (por ejemplo). Usando Javascript (y sabiendo que la mayoría de los robots de spam automatizados no ejecutarán JS), oculte el campo y rellene con 'Alex'. Si el formulario enviado no tiene la palabra mágica allí, ignórelo.
Los usuarios con JS no lo verán y estarán bien. Los usuarios sin JS simplemente tendrán que seguir las instrucciones simples. Los Spambots no sabrán qué hacer y usted puede ignorar su entrada.
Esto lo protegerá del 99.9% de los robots de spam automatizados. Lo que no hará, incluso en lo más mínimo, es salvaguardarlo contra un ataque dirigido. Alguien podría personalizar su bot para evitar el honeypot o siempre completar el valor correcto.
Respecto de bloqueo de fuerza bruta: Una solución de servidor es el único camino viable para hacer esto obviamente. Para uno de mis proyectos actuales, implementé un sistema de protección de fuerza bruta muy similar a lo que describes. Se basó en este Brute Force Protection plugin para CakePHP.
El algoritmo es bastante simple, pero un poco confuso inicialmente.
- El usuario solicita algún tipo de acción (restablecer la contraseña, por ejemplo)
- Run:
DELETE * FROM brute_force WHERE expires < NOW()
Run:
SELECT COUNT(*) FROM brute_force
WHERE action = 'passwordReset'
AND ip = <their ip address>
- Si el recuento es mayor que
X
luego diles que esperar un poco .
De lo contrario, ejecute:
INSERT INTO brute_force (ip, action, expires)
VALUES (<their ip address>, 'passwordReset', NOW() + Y minutes)
- continuar con la función de restablecimiento de contraseña.
Esto permitirá a los usuarios intentar restablecer una contraseña X veces en Y minutos. Ajusta estos valores como mejor te parezca. Quizás 3 reinicios en 5 minutos? Además, podría tener diferentes valores para cada acción: para algunas cosas (p. Ej .: generar un PDF), es posible que desee restringirlo a 10 en 10 minutos.
+1 ¡Gracias por el saludo, Nick! :) – alex