[Parte 2] Agregar Captcha a Prestashop y arreglar la base de datos

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:

	{l s='DNI / NIF / NIE'}

{/if}

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

{if isset($back)}{/if} *{l s='Required field'}

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.

[Parte 1] Prestashop. El peligro de no usar Captcha

El peligro de no usar CAPTCHA

Buenas! Esta vez voy a tratar de hablar acerca de Prestashop, un sistema de comercio electrónico de código abierto.

Leí en otro blog acerca de un “fallo” (más bien descuido o como lo quieran llamar) de esta plataforma, y es que no usa captcha, pero no solo eso, sino que su sistema de verificación de usuarios a la hora de registrarse deja bastante que desear. Por un lado, se traga correos del tipo a@a.c y por otro, es posible crear cuentas con idénticos nombres, apellidos, direcciones… Lo único que se verifica, es que no haya dos cuentas de correo electrónico exáctamente iguales.

Procedemos a analizar con Tamper Data todos los datos que pasamos a la hora de registrarnos, simplemente rellenando los campos que son obligatorios. Deste Tamper Data, podremos ver algo parecido a esto:

Para encontrar lo que queremos con mayor facilidad, fijarnos en el campo de “Método” y buscar “POST” (método que usa el formulario para enviar los datos). Una vez encontrado, copiamos el contenido de POSTDATA, y vamos a hacer lo interesante: llenar la base de datos de cuentas basura.

Como dije anteriormente… lo único que se comprueba es que no existan dos direcciones de correo iguales, asi que podrían valer:

a1@a.c
a2@a.c
a3@a.c

Como no es plan de molestarnos en hacer un programa para ello, vamos a programar un script en la conocida addon de Firefox, iMacros. iMacros permite ejecutar todo tipo de cosas dentro del navegador, podria dedicarle una entrada entera y bien larga a este complemento tan interesante, que si no conociais, ya iba siendo hora. Usaremos iMacros para repetir el proceso tantísimas veces como queramos, de forma controlada.

Antes de programar el script, vamos a ver la base de datos con usuarios de prueba que he creado, para ver el antes, y el después. Como podemos ver, solo tenemos 6 usuarios en nuestra base de datos.

Procedemos a programar el script de iMacros, el cual explicaré un poco. Lo bueno de este addon, es la facilidad y flexibilidad que permite su código. Como vamos a ver, con 2 líneas habremos conseguido lo que queriamos:

1 URL GOTO=http://delanover.com/shop/authentication.php?POSTDATA=customer_firstname=nombre&customer_lastname=apellidos&email=delanover{{!loop}}%40a.c&passwd=password&days=&months=&years=&company=&firstname=nombre&lastname=apellidos&address1=asddd&address2=&postcode=1234&city=asddd&id_country=6&id_state=&other=&phone=&phone_mobile=&alias=Mi+direcci%C3%B3n&dni=&email_create=1&back=my-account.php&submitAccount=Registrarse
2 URL GOTO=http://delanover.com/shop/index.php?mylogout

La primera línea nos manda a esa dirección, en la cual, como podemos comprobar, están los datos que hemos recogido de Tamper Data anteriormente, precedidos de “http://delanover.com/shop/authentication.php?”. La interrogación es para separar, y el resto, es la dirección en donde nos registramos. Esto nos permite registrarnos con una sola línea.
La segunda línea, nos dirige a un enlace que nos desloguea. Es decir que lo que hacemos es: Registrarnos -> Desloguearnos -> Registrarnos -> Desloguearnos -> .. y así sucesivamente.

Prestamos atención a la variable {{!loop}} que se encuentra en la primera línea, en el correo. Esta variable, se irá incrementando en uno a medida que aumenta el bucle, así obtendremos cuentas de correo del tipo delanover1@a.c, delanover2@a.c, delanover3@a.c, …

Ahora sencillamente, ponemos el navegador, iniciamos el iMacros, seleccionamos el rango del bucle (desde 1, hasta 200 por ejemplo) y a esperar. Lo malo de esto es que no podremos usar el ordenador hasta que acabe (alguna pega tendria que tener) así que lo dejamos un rato corriendo y seguimos. Resultado de 15 minutos:

Continuará…

Parte 2

Saludos, lipman