Parte 1

Recordemos la situación actual: Tenemos en nuestra base de datos un montón de cuentas introducidas con la intención de llenar nuestra base de datos, así que lo primero será borrarlas, y lo segundo intentar que no lo puedan volver a repetir introduciendo un Captcha para la verificación. También ayudaría banear la IP del atacante, excepto si lo hiciese con una botnet (vaya tipo…).

Borrando las cuentas basura
Para lo siguiente, vamos a tener que analizar la situación. En la situación actual, podemos darnos cuenta de que las cuentas son del tipo delanoverN@a.c, por lo que podemos recorrer la base de datos mirando cada cuenta de correo y borrándola si concuerda con el patrón usado por el atacante. Esto sería muy sencillo, puesto que simplemente, podriamos mirar a partir del arroba, ya que el dominio a.c no existe, así que podríamos recoger la cadena, y comprobar si desde el arroba hasta el final, contiene “a.c”.

Para esto, podemos irnos directamente a la base de datos e introducir la orden para eliminar, o desde un fichero php:

$consulta = "DELETE FROM ps_customer WHERE email REGEXP '@a\.c'";
$resultado = mysql_query($consulta);

Esta forma nos permite usar expresiones regulares, y detectará todas las que contengan @a.c, eliminándolas. En caso de complicarse más… se podría mirar la fecha de registro y eliminar a todos los usuarios registrados siguiendo cierto patrón, aunque esto es peligroso ya que podriamos eliminar a más de un usuario real.

Agregando el sistema de CAPTCHA a Prestashop

Aquí, la parte más interesante para los que quieran usar Prestashop, puesto que ya hemos visto el peligro que corremos si no disponemos del captcha. Vamos a usar reCaptcha, el captcha de Google. El primer paso es registrarnos, tras el cual, nos darán dos claves, una pública y una privada. La primera se encarga de que el sistema pueda saber qué página web le está llamando (en nuestro caso, la nuestra). Y la segunda clave, es la verificación del captcha.

Tras registrarnos, procedemos a descargarnos y subir a nuestro servidor los ficheros necesarios para el funcionamiento de este. Estos se encuentran en el siguiente enlace.

Una vez subidos los archivos, procedemos a la inserción del código (y a una modificación que tendremos que hacer). Para ello vamos a explicar cómo funciona a rasgos generales el código de la página, y que si no tenemos conocimientos de programación web, puede resultar un poco más complicado de entender.

Como podemos ver en el enlace a la hora de registrarnos, el archivo encargado de esto, se llama authentication.php y se encuentra en el directorio raiz de la tienda electrónica. Vamos a ver las últimas líneas de este fichero:

include(dirname(__FILE__).'/header.php');
$smarty->assign('errors', $errors);
Tools::safePostVars();
$smarty->display(_PS_THEME_DIR_.'authentication.tpl');
include(dirname(__FILE__).'/footer.php');

Podemos ver que, incluye la cabecera, luego una plantilla tpl, y finalmente el pie de página o footer. Antes de empezar a toquetear, debemos de tener claro dónde queremos colocar el captcha. Yo he decidido colocarlo justo antes del submit del formulario, es decir, entre el “Tax Identification” y el botón Register. Sin embargo, a priori no puedo meter el código, ya que para esto, tendría que dividir la plantilla en dos partes. Espero que se entienda un poco mejor esta aclaración con la siguiente imagen:

Conclusión: tenemos que dividir la plantilla en dos partes para poder introducir en medio nuestro código para llamarlo, así que vayamos a ello.

División de la plantilla en dos partes
La plantilla se encuentra en /themes/prestashop/authentication.tpl. Para empezar, renombraremos este archivo a authentication1.tpl, y crearemos uno vacio llamado authentication2.tpl. Recordemos que nosotros queremos poner el captcha tras la autenticación del DNI, así que vamos al final del fieldset class=”account_creation dni”, de manera que este archivo tiene que acabar:

	<span class="form_info">{l s='DNI / NIF / NIE'}</span>
</p>
</fieldset>
{/if}

Nuestro archivo authentication2.tpl contendrá lo que hemos quitado de ahí, que es lo siguiente:

<p class="cart_navigation required submit">
	<input type="hidden" name="email_create" value="1" />
	{if isset($back)}<input type="hidden" class="hidden" name="back" value="{$back|escape:'htmlall':'UTF-8'}" />{/if}
	<input type="submit" name="submitAccount" id="submitAccount" value="{l s='Register'}" class="exclusive" />
	<span><sup>*</sup>{l s='Required field'}</span>
</p>
</form>

Ya tenemos dividida en dos la plantilla. Ahora tenemos que volver al authentication.php para cambiar lo que dijimos anteriormente de forma que quede de la siguiente manera:

include(dirname(__FILE__).'/header.php');
$smarty->assign('errors', $errors);
Tools::safePostVars();
$smarty->display(_PS_THEME_DIR_.'authentication1.tpl');
//Aquí irá el Captcha
$smarty->display(_PS_THEME_DIR_.'authentication2.tpl');
include(dirname(__FILE__).'/footer.php');

Agregando definitivamente el Captcha
Google también nos deja escrito una poca de ayuda para poder meter el captcha en la siguiente dirección. Seguiré explicando cómo se integra, ya que además, Prestashop autentica los datos y realiza el registro en la propia página donde se recogen, osea, no son dos páginas (una de recogida y una de verificación y creación del usuario) sino que se hace todo en la misma. Por lo que el código de “ambas páginas” lo tendremos que poner en la misma, en la de authentication.php.

Por partes: Google nos dice que en la página en donde tiene que ir el captcha, tenemos que poner el siguiente código:

require_once('recaptchalib.php');
$publickey = "your_public_key"; // you got this from the signup page
echo recaptcha_get_html($publickey);

La línea encargada de mostrar el captcha (la del echo) la colocamos justo entre medio de las dos partes de la plantilla, quedando:

include(dirname(__FILE__).'/header.php');
$smarty->assign('errors', $errors);
Tools::safePostVars();
$smarty->display(_PS_THEME_DIR_.'authentication1.tpl');
echo recaptcha_get_html($publickey);
$smarty->display(_PS_THEME_DIR_.'authentication2.tpl');
include(dirname(__FILE__).'/footer.php');

En la parte superior de la authentication.php pondremos las dos líneas que nos quedan para incluir la libreria:

require_once('recaptchalib.php');
$publickey = "xxxxxxxxxxxxxxx"; // Clave pública

Ya tenemos puesta la primera parte, pasemos a la segunda. Google nos dice que introduzcamos la siguiente:

  require_once('recaptchalib.php');
  $privatekey = "your_private_key";
  $resp = recaptcha_check_answer ($privatekey,
                                $_SERVER["REMOTE_ADDR"],
                                $_POST["recaptcha_challenge_field"],
                                $_POST["recaptcha_response_field"]);
 
  if (!$resp->is_valid) {
    // What happens when the CAPTCHA was entered incorrectly
    die ("The reCAPTCHA wasn't entered correctly. Go back and try it again." .
         "(reCAPTCHA said: " . $resp->error . ")");
  } else {
    // Your code here to handle a successful verification
  }

La explicación de este código la podriamos dividir en dos: al principio se encuentra la parte encargada de la verificación, y posteriormente (con el if-else) se encuentra la parte condicional de lo que pasa si introducimos o no correctamente el captcha.

Volvemos a la parte superior de authentication.php y agregamos más de esas líneas, quedando junto con lo anteriormente escrito, de la siguiente manera:

require_once('recaptchalib.php');
$publickey = "xxxxxxxxxxxxxxx"; // Clave pública
 
$privatekey = "xxxxxxxxxxxx"; // Clave privada
$resp = recaptcha_check_answer ($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]);

Y finalmente, pasamos a la parte condicional de qué pasará al introducir mal nuestro querido captcha. Nos vamos a la parte de los errores, que tiene que estar sobre la línea 55, que empieza así:

if (Tools::isSubmit('submitAccount'))
{
	$create_account = 1;
	$smarty->assign('email_create', 1);
	$validateDni = Validate::isDni(Tools::getValue('dni'));
	if (!Validate::isEmail($email = Tools::getValue('email')))
		$errors[] = Tools::displayError('e-mail not valid');
	if (!Validate::isPasswd(Tools::getValue('passwd')))
		$errors[] = Tools::displayError('invalid password');
	if (Customer::customerExists($email))
		$errors[] = Tools::displayError('someone has already registered with this e-mail address');

Y justo ahí detrás, introducimos las dos últimas líneas que nos quedan:

	if (!$resp->is_valid)
		$errors[] = Tools::displayError('Error entering the CAPTCHA');

Test final
Al no introducir el captcha o introducirlo incorrectamente, nos saldrá el siguiente mensaje:

Y ahora, vamos a introducir en el navegador la línea que introduciamos en la Parte 1 para que se nos registrase una cuenta automáticamente con iMacros, a ver que pasa:

Con esto, damos por concluido este “tutorial”.

Saludos, lipman.