Documente Academic
Documente Profesional
Documente Cultură
8 partes:
1. Configurar tu servidor
8. Proteger páginas
Con más y más historias de la piratería en las noticias, los desarrolladores buscan mejores maneras de asegurar su
sitio. Si tu sitio tiene un sistema de miembros, podría estar en riesgo de ser crackeado y los datos de los usuarios
podrían verse comprometidos. La presente guía te mostrará un intento de crear un inicio de sesión segura con PHP.
Hemos puesto nuestro mejor esfuerzo en programar el código, pero la seguridad y sobre todo la encriptación son
temas complejos que cambian todo el tiempo y no podemos decir que dominamos todo ese campo. Por lo tanto,
podríamos haber obviado unos cuantos trucos en nuestra programación. De ser así, háznoslos saber y trataremos de
incorporar toda mejora a lo que tenemos. Seguir la presente guía te ayudará a cuidarte de muchos tipos de ataques
que podrían emplear los crackers para apoderarse del control de las cuentas de otros usuarios, eliminar cuentas y/o
cambiar datos. A continuación te presentaremos un lista de posibles ataques de los cuales la presente guía procura
defenderse:
SQL Injections
Session Hijacking
Network Eavesdropping
Cross Site Scripting
Brute Force Attacks
El enfoque consiste en emplear una combinación de filtros de datos, encriptación y otros métodos para hacerles la
vida un poco más difícil a quienes piensen atacarte.
Tratamos de mejorar continuamente el presente script. La versión más reciente del código está disponible en
github. Podría haber algunas diferencias entre el código que descargues en esa página y el código citado en el
presente artículo. Deberás tener presente que nuestro objetivo no ha sido que la presentación de las páginas HTML
hecha por la aplicación se vea bonita en lo absoluto.
También deberás tener presente que no cerramos las etiquetas PHP en los archivos que contienen solamente código
PHP. Esto está en línea con la mayoría de recomendaciones de formato de código.
Por último, es necesario que sepas que te pedimos crear todos los archivos no-HTML de la aplicación en diversos
directorios dentro del directorio raíz de la aplicación. La manera más fácil de crear la estructura del directorio
correcto consiste en descargar el código más reciente haciendo clic en uno de los enlaces antes mencionados.
Por favor, siéntete con la libertad de usar la presente aplicación como base para tu propia implementación, pero no
la uses a modo de ejemplo de una buena práctica de programación.
Cosas que necesitarás
Debido a que estaremos utilizando mysqli_* que es un conjunto de clases PHP para acceder a nuestra base de datos
mySQL, necesitarás las siguientes versiones de PHP y MySQL.
Evidentemente, también necesitarás un servidor web configurado para usar PHP para alojar tus páginas. Este será
muy probablemente el servidor web de alojamiento de tu página, a menos que estés alojando tú mismo el sitio.
1. 1
La mayoría de los servicios de alojamiento tiene PHP y mySQL ya instalados, pero tendrás que revisar que
tengan las versiones más recientes de PHP y mySQL para que la presente guía pueda serte de ayuda. Si no
tienen al menos PHP5.3 y MySQL5, podrías poner en tela de juicio su compromiso con la seguridad.
Mantener tu software actualizado es parte del proceso de seguridad.
Si tienes tu propio servidor o computadora, deberás instalar el software requerido normalmente según tu
sistema. En general, si no vas a usar la configuración por motivos de producción y vas a desarrollar en
Windows o OS X, instalar un paquete de aplicaciones (stack) XAMPP será lo más recomendable. Consigue
la versión apropiada para tu sistema operativo en:
http://www.apachefriends.org/en/xampp.html
Sin embargo, ten presente que bajo ninguna circunstancia deberás utilizar XAMPP para crearte un
ambiente de servidor de producción.
En Linux, usa el gestor de paquetes para descargar e instalar los paquetes necesarios. Algunas
distribuciones, como Ubuntu, contienen todas las aplicaciones necesarias en un solo paquete. Tan solo
tendrás que hacer lo siguiente en una ventana de terminal de Ubuntu:
Pero aunque instales los elementos necesarios, asegúrate de configurar MySQL con una contraseña de raíz
segura.
Podrás usar el código a continuación o hacer lo mismo en phpMyAdmin o en tu cliente GUI MySQL
favorito, si lo deseas:
Nota: algunos servicios de alojamiento no te permitirán crear una base de datos con phpMyAdmin, por eso
aprende hacerlo en cPanel.
2. 2
Crear un usuario con privilegios restringidos significa que en el caso de que alguna vez se viole la
seguridad en tu secuencia de comandos, el hacker no podrá borrar ni dejar nada desde nuestra base de
datos. Al utilizar este usuario podrás hacer casi lo que quieras con tu aplicación. Si eres realmente
paranoico, crea un usuario diferente para cada función.
Claro que necesitarás haber iniciado sesión en MySQL como un usuario con los privilegios suficientes para
poder crear otro usuario. Por lo general, este usuario será raíz.
Usuario: "sec_user"
Contraseña: "eKcGZr59zAa2BEWU"
Nota: te recomendamos cambiar la contraseña del que mencionamos anteriormente cuando vayas a
ejecutarlo en tu propio servidor. Si lo haces, asegúrate también de cambiar el código a continuación y el
código de conexión de la base de datos PHP en la aplicación que crearemos.
Recuerda que no tendrá que ser una contraseña que puedas recordar, así que hazla lo más complicada
posible. Por ejemplo, este es un generador de contraseñas aleatorias.
A continuación también estará el código SQL para crear el usuario de base de datos y otorgarle los
permisos necesarios. Si lo prefieres, también podrías hacerlo en un cliente de base de datos GUI como
phpmyadmin:
3. 3
El código a continuación creará una tabla con cinco campos (identificación, nombre de usuario, correo
electrónico, contraseña, sal). Utilizaremos el tipo de datos CHAR para los campos cuya extensión
conozcamos, ya que los campos “contraseña” y “sal” siempre tendrán 128 caracteres de largo. Utilizar
CHAR en esos casos ahorrará energía de procesamiento:
Como lo hemos mencionado anteriormente, podrás hacerlo en cualquier tipo de cliente que prefieras.
4. 4
Utilizaremos esta tabla para almacenar los intentos de inicio de sesión de un usuario. Esta es una manera
con la que dificultaremos los ataques de fuerza bruta:
5. 5
Crea una fila de prueba en la tabla “miembros”.
Será importante poder ser capaz de probar el script de inicio de sesión, así que a continuación te
presentaremos el script para crear un usuario con detalles conocidos:
Username: test_user
Email: test@example.com
Password: 6ZaxN2Vzm9NUJT2y
El código que necesitarás para poder iniciar sesión como este usuario es:
1. 1
Crea una carpeta llamada “includes” en el directorio raíz de la aplicación y luego crea un archivo PHP
nuevo en ese directorio. Ponle el nombre “psl-config.php”. En un ambiente de producción, deberás ubicar
ese archivo y todos los demás archivos “include” fuera de la raíz de documentos del servidor web. Si lo
haces, cosa que te recomendamos, tendrás que alterar el “include” o las declaraciones requeridas tanto
como sea necesario para que la aplicación pueda encontrar los archivos “include”.
Si ubicas estos archivos fuera de la raíz de documentos del servidor web, no se podrá encontrar tu archivo
con un URL. Entonces, en el caso de que alguien haya dejado la extensión PHP por error o haya echado a
perder los permisos de archivo, el archivo no podrá mostrarse en texto en una ventana del buscador.
El archivo tendrá variables de configuración global. Aspectos como si alguien puede registrarse, si es una
conexión (HTTPS) segura, entre otros, además de los detalles de la base de datos podrían ir a ese lugar.
<?php
/**
* Estos son los detalles de inicio de sesión de la base de datos:
*/
define("HOST", "localhost"); // El alojamiento al que deseas conectarte
define("USER", "sec_user"); // El nombre de usuario de la base de datos
define("PASSWORD", "4Fa98xkHVd2XmnfK"); // La contraseña de la base de datos
define("DATABASE", "secure_login"); // El nombre de la base de datos
define("CAN_REGISTER", "any");
define("DEFAULT_ROLE", "member");
Este será el código PHP que tendrás que utilizar para conectarte a la base de datos mySQL. Crea un nuevo
archivo PHP llamado “db_connect.php” en el directorio de “includes” de la aplicación y agrega el código a
continuación. Luego podrás incluir el archivo en cualquier página en la que desees conectarte con la base
de datos.
<?php
include_once 'psl-config.php'; // Ya que functions.php no está incluido.
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
1. 1
Esta función hará que tu script de inicio de sesión sea mucho más seguro. Hará que los crackers dejen de
acceder al cookie de identificación de la sesión con JavaScript (por ejemplo en un ataque XSS). A su vez,
la función “session_regenerate_id()”, la cual regenera la identificación de la sesión en cada carga de la
página, ayudará a prevenir un robo de sesión. Nota: si vas a usar HTTPS en tu aplicación de inicio de
sesión, configura la variable “$secure” a “verdadero”. En un ambiente de producción, será esencial que
emplees HTTPS.
function sec_session_start() {
$session_name = 'sec_session_id'; // Configura un nombre de sesión personalizado.
$secure = SECURE;
// Esto detiene que JavaScript sea capaz de acceder a la identificación de la
sesión.
$httponly = true;
// Obliga a las sesiones a solo utilizar cookies.
if (ini_set('session.use_only_cookies', 1) === FALSE) {
header("Location: ../error.php?err=Could not initiate a safe session
(ini_set)");
exit();
}
// Obtiene los params de los cookies actuales.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly);
// Configura el nombre de sesión al configurado arriba.
session_name($session_name);
session_start(); // Inicia la sesión PHP.
session_regenerate_id(); // Regenera la sesión, borra la previa.
}
2. 2
3. 3
Los ataques de fuerza bruta son difíciles de prevenir, para hacerlo podrías utilizar pruebas de CAPTCHA,
bloquear las cuentas de usuario y agregar un retraso en los inicios de sesión fallidos, así el usuario no podrá
acceder por otros 30 segundos.
Sea cual sea el sistema que decidas usar, te sugerimos mostrar la imagen de CAPTCHA después de dos
inicios de sesión fallidos para evitar incomodar al usuario innecesariamente.
Cuando nos enfrentamos a este problema, la mayoría de los desarrolladores simplemente bloquea la
dirección IP después de cierta cantidad de inicios de sesión fallidos. Sin embargo, existen muchas
herramientas para automatizar el proceso. Estas pueden pasar por una serie de proxies e incluso cambiar la
IP en cada solicitud. Bloquear todas estas direcciones IP podría bloquear las cuentas de tus usuarios
legítimos también. En nuestro código registraremos los intentos fallidos y bloquearemos la cuenta del
usuario después de cinco intentos sin éxito. Esto hará que se envíe un correo electrónico al usuario con un
enlace para resetearlo, pero no hemos implementado este punto en nuestro código. A continuación te
presentaremos la función “checkbrute()” hasta la fecha. Agrégaselo a tu código “functions.php”:
// Todos los intentos de inicio de sesión se cuentan desde las 2 horas anteriores.
$valid_attempts = $now - (2 * 60 * 60);
4. 4
function login_check($mysqli) {
// Revisa si todas las variables de sesión están configuradas.
if (isset($_SESSION['user_id'],
$_SESSION['username'],
$_SESSION['login_string'])) {
$user_id = $_SESSION['user_id'];
$login_string = $_SESSION['login_string'];
$username = $_SESSION['username'];
if ($stmt->num_rows == 1) {
// Si el usuario existe, obtiene las variables del resultado.
$stmt->bind_result($password);
$stmt->fetch();
$login_check = hash('sha512', $password . $user_browser);
if ($login_check == $login_string) {
// ¡¡Conectado!!
return true;
} else {
// No conectado.
return false;
}
} else {
// No conectado.
return false;
}
} else {
// No conectado.
return false;
}
} else {
// No conectado.
return false;
}
}
5. 5
function esc_url($url) {
if ('' == $url) {
return $url;
}
$count = 1;
while ($count) {
$url = str_replace($strip, '', $url, $count);
}
$url = htmlentities($url);
El problema de usar una variable de servidor no filtrada es que podría usarse en un ataque de secuencias de
comandos en sitios cruzados. Según la mayoría de referencias, solo tendrás que filtrarla con
“htmlentities()”, sin embargo, sigue siendo insuficiente, por eso existen excesivas medidas de seguridad
para esta función.
Otros sugieren dejar en blanco el atributo de acción del formulario o configurarlo a una cadena vacía. Pero
hacerlo así podría dar lugar a un ataque de secuestro de clic iframe.
1. 1
Crea la página de procesamiento de inicio de sesión (process_login.php)
Crea un archivo para procesar los inicios de sesión, con el nombre “process_login.php”, en el
directorio “includes” de la aplicación. Tendrá que ir a este directorio porque no tiene ningún formato
HTML.
Usaremos la serie de funciones PHP mysqli_*, puesto que esta es una de las extensiones mySQL más
actualizadas.
<?php
include_once 'db_connect.php';
include_once 'functions.php';
if (isset($_POST['email'], $_POST['p'])) {
$email = $_POST['email'];
$password = $_POST['p']; // La contraseña con hash
2. 2
El script para el cierre de sesión deberá iniciar sesión, destruirla y luego redireccionarla a otro lugar. Nota:
te recomendamos añadir una protección CSRF aquí en el caso de que alguien logre enviar un enlace oculto
a esta página. Para mayor información sobre CSRF, visita Coding Horror.
El código actual para desconectar al usuario, el cual deberás agregar al archivo titulado “logout.php” en el
directorio “includes” de la aplicación, es el siguiente:
<?php
include_once 'includes/functions.php';
sec_session_start();
// Destruye sesión.
session_destroy();
header('Location: ../ index.php');
3. 3
Página de registro.
Deberás incluir el código de registro en dos archivos nuevos, llamados “register.php” en el directorio raíz
de la aplicación y “register.inc.php” en el directorio “includes”, lo cual hará lo siguiente:
La mayoría de la validación se hace en JavaScript, del lado del cliente. Esto se debe a que el usuario no
tiene la motivación para burlar estas verificaciones. ¿Por qué querría el usuario crearse una cuenta que no
sería tan segura? Hablaremos de JavaScript en la siguiente sección.
Por ahora, solo tendrás que crear el archivo “register.php” e incluye el código a continuación:
<?php
include_once 'includes/register.inc.php';
include_once 'includes/functions.php';
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Secure Login: Formulario de registro</title>
<script type="text/JavaScript" src="js/sha512.js"></script>
<script type="text/JavaScript" src="js/forms.js"></script>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<!-- Formulario de registro que se emitirá si las variables POST no se
establecen o si la secuencia de comandos de registro ha provocado un error. -
->
<h1>Regístrate con nosotros</h1>
<?php
if (!empty($error_msg)) {
echo $error_msg;
}
?>
<ul>
<li> Los nombres de usuario podrían contener solo dígitos, letras
mayúsculas, minúsculas y guiones bajos.</li>
<li> Los correos electrónicos deberán tener un formato válido. </li>
<li> Las contraseñas deberán tener al menos 6 caracteres.</li>
<li>Las contraseñas deberán estar compuestas por:
<ul>
<li> Por lo menos una letra mayúscula (A-Z)</li>
<li> Por lo menos una letra minúscula (a-z)</li>
<li> Por lo menos un número (0-9)</li>
</ul>
</li>
<li> La contraseña y la confirmación deberán coincidir exactamente.</li>
</ul>
<form action="<?php echo esc_url($_SERVER['PHP_SELF']); ?>"
method="post"
name="registration_form">
Nombre de usuario: <input type='text'
name='username'
id='username' /><br>
Correo electrónico: <input type="text" name="email" id="email" /><br>
Contraseña: <input type="password"
name="password"
id="password"/><br>
Confirmar contraseña: <input type="password"
name="confirmpwd"
id="confirmpwd" /><br>
<input type="button"
value="Register"
onclick="return regformhash(this.form,
this.form.username,
this.form.email,
this.form.password,
this.form.confirmpwd);" />
</form>
<p>Return to the <a href="index.php">login page</a>.</p>
</body>
</html>
<?php
include_once 'db_connect.php';
include_once 'psl-config.php';
$error_msg = "";
if ($stmt->num_rows == 1) {
// Ya existe otro usuario con este correo electrónico.
$error_msg .= '<p class="error">A user with this email address already
exists.</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
if ($stmt) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// Ya existe otro usuario con este nombre de usuario.
$error_msg .= '<p class="error">A user with this username
already exists</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error line 55</p>';
$stmt->close();
}
// Pendiente:
// También habrá que tener en cuenta la situación en la que el usuario no tenga
// derechos para registrarse, al verificar qué tipo de usuario intenta
// realizar la operación.
if (empty($error_msg)) {
// Crear una sal aleatoria.
//$random_salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));
// Did not work
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
Si no hay ningún dato POST provisto al formulario, se mostrará el formulario de registro. El botón de
envío del formulario llama a la función de JavaScript “regformhash()”. Esta función realizará las
verificaciones de validación necesarias y enviará el formulario cuando todo sea correcto. Hablaremos de
las funciones de JavaScript en la siguiente sección.
Si existen datos POST, se realizarán algunas verificaciones del servidor para sanearlos y validarlos. TEN
PRESENTE que estas verificaciones no están culminadas hasta la fecha. Algunos de los problemas se
mencionan en los comentarios en el archivo. A la fecha, solo verificamos que la dirección de correo
electrónico tenga el formato correcto, que la contraseña con hash tenga la extensión correcta y que el
usuario no trate de registrar un correo electrónico ya registrado.
Si todo es correcto, se registrará al nuevo usuario y se escribirá un registro nuevo en la tabla de miembros.
1. 1
Este archivo es una implementación en JavaScript del algoritmo hash sha512. Haremos uso de la función
hash para que las contraseñas no se envíen en texto simple.
Guarda tu copia de este archivo en un directorio titulado “js” en el directorio de raíz de la aplicación.
2. 2
re = /^\w+$/;
if(!re.test(form.username.value)) {
alert("El nombre de usuario deberá contener solo letras, números y guiones
bajos. Por favor, inténtelo de nuevo");
form.username.focus();
return false;
}
var re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}/;
if (!re.test(password.value)) {
alert('Las contraseñas deberán contener al menos un número, una letra minúscula
y una mayúscula. Por favor, inténtelo de nuevo');
return false;
}
// Crea una entrada de elemento nuevo, esta será nuestro campo de contraseña con
hash.
var p = document.createElement("input");
En ambos casos, JavaScript le pone un hash a la contraseña y la transfiere a los datos POST al crear y
rellenar un campo escondido.
Esta es una forma de HTML con dos campos de texto, titulados “correo electrónico” y “contraseña”. El
botón de envío del formulario llamará a la función de JavaScript “formhash()”, la cual generará una
contraseña con hash y enviará el contenido de “correo electrónico” y “p” (contraseña con hash) al servidor.
Deberás crear este archivo en el directorio de raíz de la aplicación.
Al iniciar la sesión, lo más recomendable será utilizar algo que no sea público. En la presente guía
usaremos el correo electrónico como ID de inicio de sesión, pero el nombre de usuario podrá utilizarse
después para identificar al usuario. Si el correo electrónico se oculta en alguna página dentro de la
aplicación más amplia, se añadirá otra variable desconocida para crackear las cuentas.
Nota: pese a que hemos encriptado la contraseña de modo que no se envíe en texto simple, será vital que
uses el protocolo HTTPS (TLS/SSL) a la hora de enviar las contraseñas a un sistema de producción. No
está por demás insistir en que simplemente poner un hash a la contraseña será insuficiente. Podrías sufrir
un ataque “man-in-the-middle” que podría leer el hash enviado y usarlo para iniciar sesión.
<?php
include_once 'includes/db_connect.php';
include_once 'includes/functions.php';
sec_session_start();
if (login_check($mysqli) == true) {
$logged = 'in';
} else {
$logged = 'out';
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Secure Login: Log In</title>
<link rel="stylesheet" href="styles/main.css" />
<script type="text/JavaScript" src="js/sha512.js"></script>
<script type="text/JavaScript" src="js/forms.js"></script>
</head>
<body>
<?php
if (isset($_GET['error'])) {
echo '<p class="error">Error Logging In!</p>';
}
?>
<form action="includes/process_login.php" method="post" name="login_form">
Correo electrónico: <input type="text" name="email" />
Contraseña: <input type="password"
name="password"
id="password"/>
<input type="button"
value="Login"
onclick="formhash(this.form, this.form.password);" />
</form>
<p> Si no tiene una cuenta, por favor<a href="register.php">regístrese.</a></p>
<p> Si ha terminado, por favor<a href="includes/logout.php">cierre la
sesión.</a></p>
<p>Está conectado.<?php echo $logged ?>.</p>
</body>
</html>
2. 2
Crea una página web PHP nueva que lleve por nombre “register_success.php” en el directorio raíz de la
aplicación. Esta es la página a donde se le redireccionará al usuario después de haberse registrado con
éxito. Claro que podrás hacer esta página como quieras o podrás redireccionarlo a otra página (o no).
Dependerá de ti. Deberás ubicar la página en el directorio raíz de la aplicación. La página actual
“register_success.php” que hemos escrito se ve así:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Inicio de sesión segura: Registro exitoso</title>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<h1>¡Registro exitoso!</h1>
<p>Ahora podrás regresar a<a href="index.php">la página de inicio de sesión
</a> e iniciar la sesión.</p>
</body>
</html>
3. 3
Crea una página HTML nueva en el directorio raíz de la aplicación y ponle por nombre “error.php”. Esta es
la página a donde se le redireccionará al usuario en el caso de que ocurra algún error durante el proceso de
inicio de la sesión, de registro o cuando se trate de establecer una sesión segura. El código a continuación
simplemente mostrará una página de error general. Tal vez necesites algo un poco más sofisticado. No
obstante, ten presente que todo lo que se agregue a la página se deberá filtrar adecuadamente para
protegerse contra posibles ataques XSS. El código de ejemplo de la página es el siguiente:
<?php
$error = filter_input(INPUT_GET, 'err', $filter = FILTER_SANITIZE_STRING);
if (! $error) {
$error = “Ocurrió un error desconocido”;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Secure Login: Error</title>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<h1>Hubo un problema.</h1>
<p class="error"><?php echo $error; ?></p>
</body>
</html>
Parte 8 de 8: Proteger páginas
1. 1
Uno de los problemas más comunes con los sistemas de autenticación es que el desarrollador olvida
verificar si el usuario está conectado. Será de suma importancia que emplees el código a continuación en
cada página protegida para verificar que el usuario esté conectado. Asegúrate de emplear esta función.
Como ejemplo de lo que deberás hacer, hemos incluido una página protegida de muestra. Crea un archivo
con nombre “protected_page.php” en el directorio raíz de la aplicación. El archivo deberá ser parecido a lo
que mostraremos a continuación:
<?php
include_once 'includes/db_connect.php';
include_once 'includes/functions.php';
sec_session_start();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Inicio de sesión segura: Página protegida</title>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<?php if (login_check($mysqli) == true) : ?>
<p>¡Bienvenido, <?php echo htmlentities($_SESSION['username']); ?>!</p>
<p>
Este es un ejemplo de página protegida. Para acceder a esta página,
los usuarios
deberán iniciar su sesión. En algún momento, también verificaremos el
rol
del usuario para que las páginas puedan determinar el tipo de usuario
autorizado para acceder a la página.
</p>
<p>Regresar a la<a href="index.php">página de inicio de sesión.</a></p>
<?php else : ?>
<p>
<span class="error">No está autorizado para acceder a esta
página.</span> Please <a href="index.php">login</a>.
</p>
<?php endif; ?>
</body>
</html>
Nuestra aplicación redireccionará al usuario a esta página tras haberse registrado con éxito. Evidentemente,
tu implementación no tendrá que ser igual.
Consejos
Aléjate de la función md5 en los scripts de inicio de sesión, el algoritmo hash md5 se considera inseguro.
Con muy pocos cambios en estos scripts de ejemplos podrás trabajar con otros sistemas SQL, tales como
SQLite o PostgreSQL.
Usa HTML y CSS para dar formato al formulario de acceso y de salida de las páginas de tu agrado.
Si quieres usar un algoritmo hash diferente en lugar de sha512, prueba Whirlpool. Evita usar Gost, sha1 (a
menos que esté bien salado y tenga varias iteraciones) y, como ya lo hemos mencionado, md5. Incentiva a
tus usuarios a crear contraseñas únicas, seguras, con letras mayúsculas, minúsculas, números y símbolos.
Considera la posibilidad de pedirles a tus usuarios crear un nombre de inicio de sesión aparte de su nombre
de usuario para que sea más seguro.
Advertencias
La página de inicio y de registro deberán emplear HTTPS. Los scripts del presente artículo no te obligan a
hacerlo y, en realidad, sería más fácil no hacerlo durante el desarrollo, pero no deberás usar estos scripts en
un ambiente de producción a menos que utilices HTTPS.
Asegúrate de que el usuario no pueda ver tus scripts PHP, lo cual podría ocurrir debido a una configuración
incorrecta del servidor. Existe la posibilidad de que los usuarios recojan información acerca de tu base de
datos como los nombres y contraseñas si tu código PHP es visible. Lo ideal sería que todas las secuencias
de comandos incluidas en otras secuencias o páginas estén ubicadas en un directorio fuera del sistema de
archivos del servidor y que se haga referencia a ellas con un camino relativo, por ejemplo, agrega:
“../../includes/myscript.inc.php”.
Nada es 100% seguro. Recuerda mantenerte al tanto de las últimas noticias de seguridad para seguir
mejorando la seguridad de tus scripts.
Esta secuencia de comandos anti fuerza bruta que bloquea la cuenta de un usuario podría emplearse de
manera errónea muy fácilmente. Te recomendamos firmemente usar una técnica anti fuerza bruta como
CAPTCHA.
Te recomendamos usar un CAPTCHA en la página de inicio de sesión para dificultar los ataques de fuerza
bruta y DoS. El CAPTCHA deberá aparecer en el formulario después de dos intentos de inicio de sesión
fallidos, aunque todavía no está implementado en el código de ejemplo.
Podrías conseguir una mejor solución con un marco como Zend 2, Symfony o CakePHP. Todos estos
marcos tienen arreglos para las sesiones seguras y módulos de seguridad para ayudar con el proceso de
inicio de sesión. También, si utilizas un marco, probablemente veas que escribes mejores aplicaciones.
Referencias
http://crackstation.net/hashing-security.htm Hash de contraseña
https://www.owasp.org/index.php/SQL_Injection Información sobre inyección SQL