Sesiones

 
 

Importancia de la seguridad en los aplicativos web

 

-para evitar robos en el sistemas.

-Es importante la seguridad informática para que haya confiabilidad en el sistema

-para evitar perder información

- para evitar tener pérdidas económicas.

-para evitar demandas legales al no proteger la información adecuadamente.

-para tener un control del sistema.

 

Prácticas básicas de seguridad web

 
 

Balancear riesgo y usabilidad

Si bien la usabilidad y la seguridad en una aplicación web no son excluyentes una de la otra, alguna medida tomada para incrementar la seguridad con frecuencia afecta la usabilidad. Normalmente siempre se debe pensar en las maneras en que usuarios ilegítimos nos pueden atacar y la facilidad de uso para los usuarios legítimos.

Es conveniente emplear medidas de seguridad que sean transparentes a los usuarios y que no resulten engorrosas en su empleo. Por ejemplo, el uso de un login que solicita el nombre de usuario y contraseña (Ilustración 2.), permite controlar el acceso de los usuarios hacia secciones restringidas de la aplicación. Este paso adicional, es una característica que impacta en la rapidez de acceso a la información por parte del usuario, pero que proporciona un elemento adicional de protección.

A mayor complejidad de nuestro sitio, aumenta el riesgo de que se sufra un ataque debido a sus características más elaboradas, es por eso que deben considerarse opciones de seguridad necesarias y sencillas pero eficientes, que ayuden a mitigar cualquier característica que la haga vulnerable.

Rastrear el paso de los datos

Es muy importante mantener conocimiento de los pasos que ha recorrido la información en todo momento. Conocer de dónde vienen los datos y hacia dónde van. En muchas ocasiones lograr esto puede ser complicado, especialmente sin un conocimiento profundo de cómo funcionan las aplicaciones web.

En las aplicaciones web, existen maneras de distinguir los orígenes de los datos y poder así reconocer cuando los datos pueden ser dignos de confianza y cuando no.

Normalmente existen arreglos globales en la aplicación (por ejemplo en PHP los arreglos $_GET,  $_POST, $_COOKIE y $_SESSION entre otros) que sirven para identificar de forma clara las entradas proporcionadas por el usuario. Si esto lo combinamos con una convención estricta para el nombrado de las variables podemos tener un control sobre el origen de los datos usados en el código.

Además de entender los orígenes de la información se debe dar la misma importancia a entender cuáles son las salidas que tiene la aplicación y hacia a donde se devuelven los resultados.

 Filtrar entradas

El filtrado es una de las piedras angulares de la seguridad en aplicaciones web. Es el proceso por el cual se prueba la validez de los datos. Si nos aseguramos que los datos son filtrados apropiadamente al entrar, podemos eliminar el riesgo de que datos contaminados sean usados para provocar funcionamientos no deseados en la aplicación.

Existen muchos puntos de vista diferentes sobre cómo realizar el filtrado o proceso de limpieza. Lo que usualmente se recomienda es ver al filtrado como un proceso de inspección, no debemos tratar de corregir los datos, es mejor forzar a los usuarios a jugar con las reglas válidas.

Al usar listas blancas asumimos que los datos son inválidos a menos que prueben ser validos al encontrarse patrones coincidentes. Una limitante de usar este punto de vista es considerar inválidos datos que debieron considerarse válidos pero que no fueron tomados en cuenta patrones similares al construir la lista blanca.

Si llegamos a utilizar algún framework se debe tener especial cuidado, ya que estos brindan tantas comodidades que muchos desarrolladores inexpertos los utilizan sin preocuparse en entender el código que están observando y por lo tanto implementan medidas de validación en entradas, variables, entre otros, sin entender exactamente el funcionamiento de la solución empleada.

Es importante notar que en los lenguajes de programación existen una buena cantidad de filtros pero evidentemente estos no llegan a cubrir  todas las necesidades que puede tener un desarrollador. En este caso, se llegan a utilizar funciones creadas y adaptadas a nuestras necesidades a modo de filtro especial, en la mayoría de estos casos es donde se puede encontrar el uso de expresiones regulares.

En la Ilustración 3 tenemos un ejemplo en PHP de variables GET sanitizadas mediante una función la cual valida que únicamente sean números enteros (FILTER_SANITAZE_NUMBER_INT) y no contengan etiquetas HTML (strip_tags).

Escapado de salidas

Otro punto importante de la seguridad es el proceso de escapado y su contraparte para codificar o decodificar caracteres especiales de tal forma que su significado original sea preservado. Si llegamos a utilizar una codificación en particular es necesario conocer los caracteres reservados los cuales serán necesarios escapar.

El proceso de escapado debe estar compuesto a su vez por los siguientes pasos:

  •    Identificar las salidas.
  •    Escapar las salidas.
  •    Distinguir entre datos escapados y no escapados.

El proceso de escapado debe adecuarse al tipo de salida de que se trate (si es al cliente, a la base de datos, etcétera). Para la mayoría de los destinatarios, existen funciones nativas en los lenguajes de programación para esta finalidad. En alguno de los casos como podría ser el de base de datos es importante incluso observar la codificación en la que son enviados.

Para distinguir entre los datos que han sido escapados de los que no, es recomendable también usar una convención de nombres. Es necesario una función de escapado para cada caso, como ejemplo en PHP se tomarían las siguientes consideraciones para:

  •   Correo electrónico, se puede usar la función filter_var() con los argumentos de FILTER_VALIDATE_EMAIL.
  •   Bases de datos SQL, es más recomendable utilizar consultas parametrizadas pero podríamos utilizar mysql_real_escape_string.
  •   Líneas de comandos, se puede hacer uso de la función escapeshellarg().
  •  Código en Javascript, PHP no tiene un método incorporado para escaparlo, pero se puede utilizar json_encode() junto   con htmlspecialchars() si se quiere mostrar en HTML.
 
 
EXTRAIDO DE : https://www.seguridad.unam.mx/documento/?id=17
 

Creacion de usuarios y cierrre de sesion

 
 
como sabrán los archivos php que veremos a continuación se deberán de copiar en la carpeta donde Apache permite las publicaciones de las páginas web. Para el caso de haber hecho la instalación en Ubuntu, generalmente la dirección es: /var/www
 
Si utiliza tecnología como XAMPP en Windows, los archivos se deberían de copiar en c:\xampp\htdocs.
 
Lo primero es, crear nuestro archivo index.php, el cual será el primer archivo que se invoque para nuestro inicio de sesión. Prácticamente es puro HTML por lo que no se explicará mucho al respecto. Se dejó lo más sencillo posible para efectos didácticos.

 



Usuario:

Clave:

 
 
Como se ve en el archivo index.php, el
direcciona al archivo control.php el cuál sería el archivo encargado de realizar la validación del usuario y contraseña ingresado. A continuación, se muestra el archivo control.php
 
/* A continuación, realizamos la conexión con nuestra base de datos en MySQL */ 
$link = mysql_connect("localhost","root","123456"); 
mysql_select_db("base_datos", $link); 
 
/* El query valida si el usuario ingresado existe en la base de datos. Se utiliza la función htmlentities para evitar inyecciones SQL. */ 
$myusuario = mysql_query("select idusuario from usuarios where idusuario = '".htmlentities($_POST["usuario"])."'",$link); 
$nmyusuario = mysql_num_rows($myusuario); 
 
//Si existe el usuario, validamos también la contraseña ingresada y el estado del usuario... 
if($nmyusuario != 0)
  $sql = "select idusuario from usuarios where estado = 1 and idusuario = '".htmlentities($_POST["usuario"])."' and clave = '".md5(htmlentities($_POST["clave"]))."'"; 
  $myclave = mysql_query($sql,$link); 
  $nmyclave = mysql_num_rows($myclave); 
  //Si el usuario y clave ingresado son correctos (y el usuario está activo en la BD), creamos la sesión del mismo. 
  if($nmyclave != 0)
  { 
      session_start(); 
      //Guardamos dos variables de sesión que nos auxiliará para saber si se está o no "logueado" un usuario 
      $_SESSION["autentica"] = "SIP"; 
      $_SESSION["usuarioactual"] = mysql_result($myclave,0,0); 
      //nombre del usuario logueado. 
      //Direccionamos a nuestra página principal del sistema. 
      header ("Location: app.php"); 
   }
   else{ 
      echo""; 
   } 
}
else
    echo""; 
mysql_close($link); ?>
 
Como podemos apreciar del código (muy sencillo por cierto) hacemos una validación de la información ingresada por el usuario (usuario y contraseña) contra la información que están en la base de datos, para así finalmente, si todo esta bien, se direcciona a la aplicación principal; sino, muestra un mensaje de alerta indicando el problema. Ahora, no hemos hablado de la base de datos, por lo que a continuación realizaremos la creación de la misma y crearemos la tabla de usuarios (sencilla). Lo primero, es entrar a PHPMyAdmin así: https://localhost/phpmyadmin Nos autenticamos con nuestro usuario y contraseña y, una vez adentro, se da clic en “Base de Datos” para luego agregar el nombre de nuestra base de datos y damos clic en Crear. autentica01En la parte izquierda ahora nos aparecerá la base de datos que creamos, por lo que damos clic en ella y en la parte derecha nos preguntará si queremos crear una tabla. Colocamos el nombre de la tabla, colocamos el # de columnas (para el ejemplo, con 3 campos nos basta: Usuario, Clave y Estado) y damos clic en “Continuar” autentica02Ahora, colocamos el nombre de nuestros campos, el tipo de datos, la longitud y, en el caso del campo idusuario, le diremos que será llave primaria. Ver la siguiente imagen para mayor referencia. autentica03Ahora, bajamos mediante la barra vertical de la ventanita y damos clic en “Guardar” para crear nuestra tabla. autentica05Ahora, damos clic al botón “Insertar” para poder insertar un registro de prueba, y colocamos los nuevos valores (ver la imagen para mayor referencia) y finalmente damos clic en “Continuar”. autentica06
Continuando con la programación en PHP… Ahora, crearemos el archivo app.php qué, según se vió en el archivo anterior, es donde se direcciona cuando el usuario ha ingresado correctamente el usuario y contraseña.
 
Pongamos atención a la primera línea… Estamos incluyendo a la página un archivo php específico el cuál éste validará si existe una sesión válida para poder mostrar la página. Si el archivo seguridad.php determina que existe una sesión válida, se termina de mostrar la página. Véase también la línea en donde está el código: echo $_SESSION[“usuarioactual”] ; Con ésto estamos mostrando el nombre del usuario que se autenticó. Dejamos un vínculo al archivo salir.php el cual es el encargado de terminar la sesión activa del usuario. Veamos el contenido del archivo seguridad.php
 
//Reanudamos la sesión 
@session_start(); 
//Validamos si existe realmente una sesión activa o no 
if($_SESSION["autentica"] != "SIP")
  //Si no hay sesión activa, lo direccionamos al index.php (inicio de sesión) 
  header("Location: index.php"); 
  exit(); 
?>
Aqui vemos la parte de seguridad de éste sistema… Si alguien mal intencionado quisiera entrar, sin pasar por el inicio de sesión, a app.php, como existe una validación mediante el archivo seguridad.php, automáticamente se le redireccionará al inicio de sesión. Mientras no haya un inicio de sesión correcto, no se puede mostrar el archivo app.php, por lo que todas las páginas que creamos del sistema deberán de tener el include(“seguridad.php”) para que así valide si realmente el usuario está autenticado. Finalmente, veamos el archivo salir.php

 

//Reanudamos la sesión 
session_start(); 
//Literalmente la destruimos 
session_destroy(); 
//Redireccionamos a index.php (al inicio de sesión) 
header("Location: index.php"); 
?>
Y así cerramos la sesión. Si bien es cierto no es la mejor forma de autenticación que existe en el mundo PHP, es la más sencilla a mi criterio y pues se sigue implementando.

 

Extraido De: https://www.ingdiaz.org/control-sesiones-autenticacion-usuarios-usando-php-mysql/

 

Encriptacion de contraseñas

 

¿Por qué debo usar hash en las contraseñas de los usuarios de mi aplicación?

El hash de contraseñas es una de las consideraciones de seguridad más elementales que se deben llevar a la práctica al diseñar una aplicación que acepte contraseñas de los usuarios. Sin hashing, cualquier contraseña que se almacene en la base de datos de la aplicación podrá ser robada si la base de datos se ve comprometida, con lo que inmediatamente no sólo estaría comprometida la aplicación, sino también las cuentas de otros servicios de nuestros usuarios, siempre y cuando no utilicen contraseñas distintas.

Si aplicamos un algoritmo hash a las contraseñas antes de almacenarlas en la base de datos, dificultamos al atacante el determinar la contraseña original, pese a que en un futuro podrá comparar el hash resultanente con la contraseña original.

Sin embargo, es importante tener en cuenta que el hecho de aplicar hash a las contraseñas sólo protege de que se vean comprometidas las contraseñas almacenadas, pero no las proteje necesariamente de ser interceptadas por un código malicioso inyectado en la propia aplicación.

¿Por qué las funciones hash más comunes como md5() y sha1() no son adecuadas para las contraseñas?

Los algoritmos hash como MD5, SHA1 o SHA256 están diseñados para ser muy rápidos y eficientes. Con las técnicas y equipos modernos, es algo trivial extraer por fuerza bruta la salida de estos algoritmos, para determinar los datos de entrada originales.

Dada la velocidad con que los ordenadores actuales pueden "invertir" estos algoritmos hash, muchos profesionales de la seguridad recomiendan encarecidamente no utilizarlas como funciones hash para contraseñas.

¿Qué hash debo aplicar a mis contraseñas, si las funciones hash más comunes no son adecuadas?

Al aplicar un algoritmo hash, los dos factores más importantes son el coste computacional y la sal. Cuanto más cueste aplicar un algoritmo hash, más costará analizar su salida por fuerza bruta.

PHP 5.5 proporciona una API de hash de contraseñas nativa que maneja cuidadosamente el empleo de hash y la verificación de contraseñas de una manera segura. También hay una » biblioteca de compatibilidad de PHP pura disponible para PHP 5.3.7 y posterior.

Otra opción es la función crypt(), la cual tiene soporte para varios algoritmos hash en PHP 5.3 y posterior. Al emplear esta función, se garantiza que el algoritmo que se seleccione esté disponible, debido a que PHP contiene implementaciones nativas de cada algoritomo soportado, en caso de que el sistema no tenga soporte para uno o más de estos algoritmos.

El algoritmo recomendado para el empleo de contraseñas con hash es Blowfish, que es también el predeterminado de la API de hash de contraseñas, que, aunque es significativamente más caro computacionalmente que MD5 o SHA1, sigue siendo escalable.

Observar que si se emplea crypt() para verificar una contraseña, será necesario tomar precauciones para evitar ataques de temporización utilizando una comparación de string de tiempo constantes. Ni losoperadores == y === de PHP ni strcmp() llevan a cabo una comparación de string de tiempo constante. Debido a que password_verify() hará esto de forma automática, se recomienda el empleo de la API de hash de contraseñas nativa siempre que sea posible.

¿Qué es una sal (salt)?

Una sal criptográfica es un dato que se utiliza durante el proceso de hash para eliminar la posibilidad de que el resultado pueda buscarse a partir de una lista de pares precalculados de hash y sus entradas originales, conocidas como tablas rainbow.

Es decir, una sal es un pequeño dato añadido que hace que los hash sean significantemente más difíciles de crackear. Existe un gran número de servicios online que ofrecen grandes listas de códigos hash precalculados, junto con sus datos de entrada originales. El uso de una sal hace muy difícil o imposible encontrar el hash resultante en cualquiera de estas listas.

password_hash() creará una sal aleatoria si no se proporciona una, siendo esta generalmente la estrategia más sencilla y segura.

¿Cómo almaceno mis sales?

Al utilizar password_hash() o crypt(), el valor devuelto incluye la sal como parte del hash generado. Este valor debería almacenarse tal cual en la base de datos, ya que incluye información sobre la función hash que se empleó y así proporcionarla directamente a password_verify() o crypt() al verificar contraseñas.

El siguiente diagrama muestra el formato de un valor devuelto por crypt() o password_hash(). Como se puede observar, son autocontenidos, con toda la información del algoritmo y la sal requerida para futuras verificaciones de contraseñas.

 


        Los componentes del valor devuelto por password_hash y crypt: en
        orden, el algoritmo elegido, las opciones del algoritmo, la sal utilizada,
        y la contraseña con hash.

Extraido de: https://php.net/manual/es/faq.passwords.php