Sistema antispam del campo oculto para WordPress

Autor: Armonth | El jueves 21 de junio del 2007 @ 04:37.

Hace tiempo Manz de Emezeta comentó una táctica poco usada pero que suele ser bastante efectiva para desechar el spam: el campo oculto.

No hace mucho me puse en contacto con Manz para tratar el tema, estaba vago y no quería romperme la cabeza implementando algo: give me the source (o algo así...) pero al final por falta de tiempo ni él me mostró el código para implementarlo ni yo me puse a mirar cómo hubiera podido hacerlo. En cualquier caso la idea está en el post mencionado de Manz. Finalmente hice una implementación y ahora toca decir qué código modificar en WordPress.

La idea es duplicar el campo de autor para que el spammer ponga su nombre (siempre cambian el campo del nombre, al igual que los usuarios) pero vamos a hacer que ese campo de más no sea leído por los lectores mediante CSS. Para explicarlo nada mejor que robarle el gráfico a Manz:

El truco del sistema antispam reside en que los spammers, por naturaleza, cambian todos los campos llamados comment, comentario, name o nombre por la publicidad que quieren hacer. ¡Perfecto! Ellos mismos han caído.

Sistema antispam, gráfico by Manz

Manos a la obra

En WordPress tenemos cuatro campos por defecto: author (nombre de usuario), email, url y comment (contenido del comentario). El único que nos interesa es el author.

Primero haremos copia de seguridad de los dos siguientes ficheros:

/wp-comment-post.php
/ruta-a-tu-plantilla/comments.php

Una vez hecho esto, abrimos el fichero comments.php:

<!-- Buscamos donde pone lo siguiente: -->

<input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" tabindex="1" />

<!-- Lo sustituimos por: -->

<input type="text" name="author" id="author" class="hid" value="author" tabindex="1" />
<input type="text" name="nombre" id="nombre" value="<?php echo $comment_author; ?>" tabindex="2" />

Con esto creamos un nuevo campo nombre que sustituirá a author. Además creamos la clase .hid en CSS para ocultar el campo antiguo:

.hid { display: none; }

Turno para el fichero wp-comments-post.php:

<!-- Buscamos el siguiente código: -->

$comment_author = trim($_POST['author']);   
$comment_author_email = trim($_POST['email']);   
$comment_author_url = trim($_POST['url']);   
$comment_content = trim($_POST['comment']);

<!-- Lo cambiamos por: -->

$comment_author = trim($_POST['nombre']);   
$comment_fake_author = trim($_POST['author']);   
$comment_author_email = trim($_POST['email']);   
$comment_author_url = trim($_POST['url']);   
$comment_content = trim($_POST['comment']);

Ahora, si os fijáis, los datos del comentario se rellenan con el contenido del input "nombre" y guardamos el contenido del input oculto atrapa-spammers ("author") como $comment_fake_author.

Por último toca que si un comentario envía el input "author" con un value="" distinto a "author" (o lo que nosotros queramos pero que coincida con el valor por defecto del input oculto en el comments.php) sea descartado por spammer. Buscamos donde pone:

if ( '' == $comment_content )   
  die( __('Error: please type a comment.') );

Y añadimos debajo:

if ( 'author' != $comment_fake_author ) // Es spam   
  die('¿Donde vas?');

El mensaje obviamente es personalizable. Yo aquí he puesto un Quieto parado, cowboy. este mensaje (en inglés obviamente) es lo que decia WordPress antes cuando comentabas muy rápido.

Por último existe un problema: los usuarios registrados por defecto envían su nombre sin el falso campo, por lo que volvemos un poco más atrás en el código y vemos esto:

if ( $user->ID ) {   
  $comment_author = $wpdb->escape($user->display_name);

Pues justo debajo añadimos:

  $comment_fake_author = "author";

Y solucionado.

Notas al margen

  • Importante: borrad la cache (wp-cache) después de los cambios. De lo contrario la gente enviará comentarios usando los datos del viejo formulario (sin el value="author") y serán descartados.

  • El sistema oculta el campo mediante CSS: si por una casualidad el lector no usa CSS verá el campo y puede rellenarlo (por tanto: provocar el error). Por suerte esto es poco probable y se puede solucionar con una nota (oculta también).

  • El sistema es una especie de captcha no intrusivo: no impide el spam manual. Sólo se aprovecha de la "estupidez" de los bots de los spammers que usan plantillas para comentar con el formulario por defecto de WordPress. Por lo que un comentario de spam manual entrará: esto sirve para desatascar akismet y que siga filtrando el spam (el cual puede dar falsos positivos).

  • Obviamente, esto no impide el spam mediante trackbacks.

Primeros resultados

Desde que lo he implementado han aparecido en el akismet 2 comentarios pero creo que ya estaban antes. Lleva varias horas sin un comentario de spam cuando mi media diaria supera los 20 por hora (+ de 500 al día).

Manz ya aseguró en su momento (y sigue hasta ahora) que desde que lo implementó no se le ha colado ni uno salvo los comentarios hechos manualmente (los cuales son indetectables).

Comentarios