Consejos para hacer más segura una web y evitar ataques

De wikipedia_IndianWebs
Saltar a: navegación, buscar



A continuación se explican algunas de las vulnerabilidades web que pude usar un atacante para acceder a nuestra web y como evitar estos ataques.


Contenido

Ataques por fuerza bruta


Una de las formas en las que un atacante puede conseguir entrar en una web es por las pantallas de login, los hacker usan scripts y ordenadores infectados para probar por fuerza bruta las diferentes combinaciones de usuario y contraseña, tienen diccionarios con de miles de palabras y prueban todas las combinaciones, tener en cuenta que si el servidor web donde se aloja la web soporta bastantes conexiones simultaneas, con estos excripts pueden probar cientos de combinaciones por segundo.

Como evitarlo: hay varias medidas a tener en cuenta para evitar estos ataques por fuerza bruta.

  • Usar usuarios y contraseñas seguras. Prohibidos los usuarios admin y contraseñas con nombres que pueden aparecer en un diccionario tipo Juan33, Barcelona2013, etc…
  • Usar un captcha en los formularios de login, con un captcha se dificulta mucho que un script pueda probar combinaciones de usuario y contraseña.
  • Programar unos segundos de espera cada 2 o 3 intentos fallidos de hacer login, mediante la función sleep se puede programar que cada x intentos fallidos de login se haga una espera de 3 o 5 segundos, para un usuario esta espera no es mucha pero para un bot hace que probar todas la combinaciones les lleve un tiempo inmenso, ya no pueden probar cientos de combinaciones por segundo.


Inyección SQL


Esta vulnerabilidad afecta principalmente a las webs programadas a medida y que realizan consultas a la base de datos para mostrarlos el resultado en la web, los casos típicos son las variables que se pasan por get tipo ?id=2 o ?noticias=44, también son vulnerables los formularios que envían por post los datos recogidos y guardan estos datos en la BBDD. Si no se protegen estas consultas a la base de datos, un atacante puede añadir a la consulta que hace la web otras instrucciones para hacer más consultas a la base de datos, esta situación es muy grave porque permite al atacante acceder a toda la base de datos, extraer la información y hasta eliminar toda la base de datos.

Como evitarlo:

  • Limpiar los datos de las variables antes de hacer la consulta para evitar que contenga a continuación otras consultas. Para que un atacante pueda concatenar otra consulta a la que hace la web tiene que usar caracteres especiales necesarios para la consulta, como comillas y paréntesis, si mediante una función limpiamos las variables de estos caracteres antes de hacer la consulta a la BBDD evitamos la inyección SQL. Al final del documento (1) encontrareis un ejemplo de función de limpieza de variables y como aplicarlo a todas la variables enviadas por post o solo a una.
  • Usar URL amigables, usando URL amigables se dificulta en gran medida la inyección SQL, ya que no se le dan pistas al atacante de que variables se están enviando y no les permite añadir a las url más instrucciones.
  • Si no se pueden usar urls amigables se pueden añadir reglas en el archivo htacces para evitar la inyecciones .


Ataques al servidor web


Toda web funciona gracias a un servidor web como apache y una motor de base de datos como mysql, esto no deja de ser software y tiene vulnerabilidades, si un hacker consigue entrar al servidor web no sirve de nada la seguridad que puedas tener en la web o lo bien que esté programada porque están dentro del servidor.

Como evitarlo: Los servidores web deben tener al dia las versiones del software para corregir todas las vulnerabilidades que puedan haber sido descubiertas. Como normalmente nosotros no gestionamos los hostings, es una tarea que deben llevar a cabo los administradores de sistemas de la empresa de hosting que tengamos contratada, por este motivo es importante contratar hostings de calidad y con un buen servicio técnico.

Ataques a otras webs de nuestro servidor compartido


Si nuestra web está alojada en un servidor compartido, significa que en el mismo servidor se alojan otras webs de las que no tenemos control de qué nivel de seguridad tienen no como están programadas. Si desde una web vecina consiguen acceder al servidor, infectarlo, hacer spam o colapsar el servidor, afectará a nuestra web independientemente de lo bien hecha que esté.

Como evitarlo: Lo aconsejable es alojar la web en servidores dedicados en los que tengamos control de todas las webs alojadas en él. Si no hay más remedio que alojarla en uno compartido, porque es del cliente o por otro motivo, se puede hacer una consulta de DNS inversa para averiguar que webs tenemos como vecinas en el servidor, y en caso de ataque pedir al hosting que nos indique cual ha sido el origen. En este web podéis comprobar que webs están alojadas en el mismo servidor que una web determinada.

Acceso a datos sensibles de la BBDD


No hay web que sea imposible de hackear, alguien con el tiempo, los conocimientos y el empeño necesarios podría acabar accediendo a los datos de nuestra web, por ese motivo es muy importante tener protegidos nuestros datos sensible, es decir si algún consigue acceder a nuestra web y a nuestra BBDD de datos, no debe encontrar datos sensibles que pueda usar.

Como evitarlo: Todos los datos sensibles de nuestra BBDD deben estar cifrados con un algoritmo lo suficientemente robusto para que sea muy difícil descifrar esos datos. Si la web debe acceder a esos datos, se debe usar un cifrado reversible. Al final del documento (2) hay un ejemplo de cifrado reversible y el enlace otro cifrado reversible para PHP muy seguro (pbkdf2).

Ejemplos y Código


(1) Para evitar las inyecciones SQL podemos usar en las consultas SQL la función (int) para convertir las variable numéricas y mysql_real_escape_string() para las variables de texto, esta funciones evitan que se puedan pasar caracteres especiales en la consulta, a continuación un ejemplo de uso de cada función:


Valores Integers

Delante del parámetro se pone (int), de esta forma si la variable es numérica la dejará pasar, en caso contrario el valor será cero.

<?php 
if(!$_GET['id']) 
 $_GET['id'] = '1'; // Da el valor por defecto 

$resultado = mysql_query(' 
 SELECT *  
 FROM noticias  
 WHERE ID = \''.(int)$_GET['id'].'\' 
', $handle); 
......... 
?>


Valores String

if($_GET['buscar']){ 
 mysql_query(' 
  SELECT *  
  FROM datos  
  WHERE palabra LIKE \'%'.mysql_real_escape_string($_GET['buscar'].'%\' 
  LIMIT 0, 30 
 ', $handle); 
.... 
}


Otra forma de evitar la inyección SQL es usando una función de limpieza que quita cualquier carácter no deseado:

Funcion para limpar variables:

function limpia($txt) {
                if (!is_array($txt)) {
                    $txt = htmlspecialchars(strip_tags(stripslashes($txt)));
                               
                    return strtr($txt, array(
                                  "\0" => "",
                                  "'"  => "&#39;",
                                  "\"" => "&#34;",
                                  "\\" => "&#92;",
                                  "<"  => "&lt;",
                                  ">"  => "&gt;",
                    ));
                }
}

function cleanData($data) {
                foreach($data as $key => $val)
                {
                               $cleaned[$key] = limpia($val);
                }
                return $cleaned;              
}


Un ejemplo de cómo usarlo para todas las variables enviadas por POST:

$_SECPOST = cleanData($_POST); // limpia todos los datos enviados por POST
                $email = $_SECPOST['email'];
                $pwd = $_SECPOST['oldpwd'];

                // Se hace en cualquier parte del código que envie variables como hacer login, etc… 
                $usuario = new user($email, $pwd);
                $uLogin = $usuario->checkpass($pwd);


Un ejemplo de cómo usarlo para limpiar una única variable:

$strid = limpia($_POST['strid']);
                $query = 'SELECT strid FROM tags WHERE strid = \''.$strid.'\' AND active = 0 LIMIT 1'; // mira si existe el código


(2) Cifrado reversible, bastante eficiente en el que solo hay que solo hay que definir la sal, que es la clave con la que se cifrará y descifrará, aquí un ejemplo de cómo cifrar i descifrar:

   $salt ='whatever_you_want';

    function simple_encrypt($text) // CIFRA
    {
        return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
    }

    function simple_decrypt($text) // DESCIFRA
    {
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $salt, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)));
    }


Este es otro robusto método de cifrado para usar en php, pbkdf2:

https://defuse.ca/source/pbkdf2-test.php

Aquí la web con más info: https://defuse.ca/php-pbkdf2.htm


--Oscar Sánchez Guiu (discusión) 12:36 4 oct 2013 (CEST)

Herramientas personales
Espacios de nombres

Variantes
Acciones
Navegación
Herramientas
Compartir
Categorías
Apps
[×] CSS
[×] Diseño
Google
[×] Joomla
[×] Magento
[×] Mobile
[×] RRHH
[×] YouTube