Introducción

Un gran problema cuando creas una pagina web que contiene un sistema de usuarios es que no caemos en la cuenta del problema de seguridad que podemos tener sino bloqueamos la IP del usuario al llegar a un numero de intentos fallidos.

Si un atacante utiliza un sistema de fuerza bruta (que es la introducción de usuarios y contraseñas predefinidas en un diccionario u otros sistemas) sin ningún tipo de restricción por intentos fallidos de conexión en un par de horas podría conseguir entrar.

Para ello hoy os enseño un sistema sencillo que al "X" numero de intentos bloquea la IP y no le permitirá volver a intentar entrar.

 undefined

Tablas (mySQL)

SQL de la Tabla SL_ACCESS. Guarda todos los intentos de conexión, tanto correctos como incorrectos. 
CREATE TABLE `SL_ACCESS` (
  `ID` INT(11) NOT NULL AUTO_INCREMENT,
  `IP` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL,
  `DATE` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `STATE` TINYINT(1) DEFAULT NULL,
  `USER` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `PASS` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
SQL de la Tabla SL_IPBLOCK. Guarda las IPS Bloqueadas.
CREATE TABLE `SL_IPBLOCK` (
`ID` INT(11) NOT NULL AUTO_INCREMENT,
`IP` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`DATE` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Ejemplo Practico

Código de PHP del archivo login.php
<?php
	//TODO: CAMBIAR CONEXION mysql Y EJECUCCION POR PDO
	//COMPROBAMOS QUE NO ESTE BLOQUEADA SU IP
	$query_IPBLOCK = mysql_query("select COUNT(IP) AS VECES from SL_IPBLOCK where IP = '" . $_SERVER['REMOTE_ADDR'] . "'");
	$IPBLOCK = mysql_fetch_array($query_IPBLOCK);
	if ($IPBLOCK['VECES']>=1){
		$ERROR='Debido a los intentos de conexion fallidos, usted se encuentra bloqueado.';
		//No dejar seguir
		//...
	}		
	
	/*
	....
		CODIGO DE VALIDACION DE USUARIO Y CONTRASEÑA
		CODIGO DE VALIDACION DE USUARIO Y CONTRASEÑA
	....
	*/
	
		//SI ES CORRECTO NO GUARDAMOS LA CONTRASEÑA
		//TODO: CAMBIAR CONEXION mysql Y EJECUCCION POR PDO
		mysql_query("insert into SL_ACCESS (IP, STATE, USER) values ('" . $_SERVER['REMOTE_ADDR']. "',1,'" . $username . "')");	
	
	//ELSE

		//SI ES INCORRECTO, GUARDAMOS LA CONTRASEÑA, SE DEBERIA DE GUARDAR ENCRYPTADA
		//TODO: CAMBIAR CONEXION mysql Y EJECUCCION POR PDO
		mysql_query("insert into SL_ACCESS (IP, STATE, USER, PASS) values ('" . $_SERVER['REMOTE_ADDR']. "',0,'" . $username . "' , '" . $password . "')");
		
		//SI ES INCORRECTO DESPUES DE GUARDAR VERIFICAMOS QUE NO LLEVE EN ESTE CASO MAS DE 3 INTENTOS FALLIDOS EN EL MISMO DIA DESDE LA MISMA IP
		$query_CountLogins = mysql_query("select COUNT(ID) AS VECES from SL_ACCESS where LEFT(DATE,10)=LEFT(NOW(),10) AND STATE=0 and IP = '" . $_SERVER['REMOTE_ADDR'] . "'");
		$CountLogins = mysql_fetch_array($query_CountLogins);
		if ($CountLogins['VECES']>=3){
			mysql_query("insert into SL_IPBLOCK (IP) values ('" . $_SERVER['REMOTE_ADDR']. "')");
			//TODO: CREARIAMOS UNA ALERTA POR EMAIL O EL SISTEMA QUE DECIDAMOS PARA PODER ENTERARNOS DEL "ATAQUE"
		}
?>