segura en mysql php
-
Upload
patricia-suarez-valero -
Category
Documents
-
view
235 -
download
0
Transcript of segura en mysql php
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 1/21
Cómo crear un script de inicio desesión segura en php y MySQL8 partes: Configurar tu servidor Configurar la base de datos MySQL
Crear la página de conexión para la base de datos Crear funciones PHP Crear páginas de procesamiento
Crear archivos de Javascript Crear páginas HTML 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 basepara tu propia implementación, pero no la uses a modo de ejemplo de una
buena práctica de programación.
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 2/21
Debido a que estaremos utilizando mysqli_* que es un conjunto de clasesPHP para acceder a nuestra base de datos mySQL, necesitarás las
siguientes versiones de PHP y MySQL.
PHP versión 5.3 o posterior
MySQL versión 4.1.3 o posterior
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.
Para revisar la versión de PHP y MySQL en tu servidor, emplea la función
phpinfo();.
1 Instala un servidor web, PHP y MySQL en tu servidor.
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:
sudo apt-get install lamp-server^ phpmyadmin
Pero aunque instales los elementos necesarios, asegúrate de configurar MySQL con
una contraseña de raíz segura.
Anuncio
Cosas que necesitarás
Parte 1 de 8: Configurar tu servidor
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 3/21
Anuncio
1 Crea una base de datos MySQL.
Inicia la sesión en tu base de datos como usuario administrador (normalmente “raíz”).
En la presente guía crearemos una base de datos llamada “inicio_seguro”.
Ve cómo crear una base de datos en phpMyAdmin.
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:
CREATE DATABASE `secure_login`;
Nota: algunos servicios de alojamiento no te permitirán crear una base de datos con
phpMyAdmin, por eso aprende hacerlo en cPanel.
2 Crea un usuario solo con los privilegios SELECCIONAR, ACTUALIZAR e
INSERTAR.
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.
Los siguientes detalles son del usuario que hemos creado:
Usuario: "sec_user"
Parte 2 de 8: Configurar la base de datos MySQL
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 4/21
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:
CREATE USER 'sec_user'@'localhost' IDENTIFIED BY 'eKcGZr59zAa2BEWU';
GRANT SELECT, INSERT, UPDATE ON `secure_login`.* TO 'sec_user'@'localhost';
Si ves que vas a eliminar registros de cualquiera de las tablas del presente módulo,
deberás agregar ELIMINAR a la lista de privilegios o sino podrías crear un usuario
diferente que tenga solamente el privilegio ELIMINAR y solo en la tabla en la quequieras borrar registros, si no quieres hacerlo en ambas. No es necesario que otorgues
el privilegio ELIMINAR en lo absoluto para el presente ejemplo de script.
Contraseña: "eKcGZr59zAa2BEWU"
3 Crea una tabla MySQL que lleve por título "miembros".
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íade procesamiento:
CREATE TABLE `secure_login`.`members` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(30) NOT NULL,
`email` VARCHAR(50) NOT NULL,
`password` CHAR(128) NOT NULL,
`salt` CHAR(128) NOT NULL
) ENGINE = InnoDB;
Como lo hemos mencionado anteriormente, podrás hacerlo en cualquier tipo de cliente
que prefieras.
4 Crea una tabla para almacenar intentos de inicio de sesión.
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:
CREATE TABLE `secure_login`.`login_attempts` (
`user_id` INT(11) NOT NULL,
`time` VARCHAR(30) NOT NULL
) ENGINE=InnoDB
Crea una fila de prueba en la tabla “miembros”.
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 5/21
5 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:
El código que necesitarás para poder iniciar sesión como este usuario es:
INSERT INTO `secure_login`.`members` VALUES(1, 'test_user', '[email protected]','00807432eae173f652f2064bdca1b61b290b52d40e429a7d295d76a71084aa96c0233b82f1feac
'f9aab579fc1b41ed0c44fe4ecdbfcdb4cb99b9023abb241a6db833288f4eea3c02f76e0d35204a
Anuncio
Username: test_user
Email: [email protected]
Password: 6ZaxN2Vzm9NUJT2y
1Crea una página de configuraciones globales.
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 datosdefine("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");
define("SECURE", FALSE); // ¡¡¡SOLO PARA DESARROLLAR!!!!
Parte 3 de 8: Crear la página de conexión para la base de datos
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 6/21
2 Crea la página de conexión para la base de datos.
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);
Anuncio
Estas funciones harán todo el procesamiento del script de conexión. Agrega
todas las funciones a la página llamada “functions.php” en el directorio
“includes” de la aplicación.
1 Inicia de manera segura la sesión PHP.
Las sesiones PHP tienen fama de no ser muy seguras, por eso será importante no
solo poner “session_start();” en la parte superior de cada página que quieras usar para
las sesiones PHP. Crearemos una función llamada “sec_session_start()”, ella iniciará
una sesión PHP de manera segura. Deberás llamar esta función en la parte superior de
toda página en la que quieras tener acceso a una variable de sesión PHP. Si estás
realmente preocupado por la seguridad y la privacidad de las cookies, échale un vistazo
al siguiente artículo: Cómo crear un sistema de administración de sesión segura en
PHP y MySQL.
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.
Crea un nuevo archivo llamado “functions.php” en el directorio “includes” de tu
aplicación y agrégale el código a continuación.
<?phpinclude_once 'psl-config.php';
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.
Parte 4 de 8: Crear funciones PHP
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 7/21
if (ini_set('session.use_only_cookies', 1) === FALSE) {
header("Location: ../error.php?err=Could not initiate a safe session (i
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 Crea la función de inicio de sesión.
Esta función comparará el correo electrónico y la contraseña con la base de datos
y, si hay una coincidencia, aparecerá como verdadero (true). Agrega esta función a tu
archivo “functions.php”:
function login($email, $password, $mysqli) {
// Usar declaraciones preparadas significa que la inyección de SQL no será posible. if ($stmt = $mysqli->prepare("SELECT id, username, password, salt
FROM members
WHERE email = ?
LIMIT 1")) {
$stmt->bind_param ('s', $email); // Une “$email” al parámetro.
$stmt->execute(); // Ejecuta la consulta preparada.
$stmt->store_result();
// Obtiene las variables del resultado.
$stmt->bind_result($user_id, $username, $db_password, $salt);
$stmt->fetch();
// Hace el hash de la contraseña con una sal única.
$password = hash('sha512', $password . $salt);
if ($stmt->num_rows == 1) {
// Si el usuario existe, revisa si la cuenta está bloqueada
// por muchos intentos de conexión.
if (checkbrute($user_id, $mysqli) == true) {
// La cuenta está bloqueada.
// Envía un correo electrónico al usuario que le informa que su cuenta está bloqueada.
return false;
} else {
// Revisa que la contraseña en la base de datos coincida
// con la contraseña que el usuario envió.
if ($db_password == $password) {
// ¡La contraseña es correcta!
// Obtén el agente de usuario del usuario.
$user_browser = $_SERVER['HTTP_USER_AGENT']; // Protección XSS ya que podríamos imprimir este valor.
$user_id = preg_replace("/[^0-9]+/", "", $user_id);
$_SESSION['user_id'] = $user_id;
// Protección XSS ya que podríamos imprimir este valor.
$username = preg_replace("/[^a-zA-Z0-9_\-]+/",
"",
$username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512',
$password . $user_browser);
// Inicio de sesión exitoso
return true;
} else {
// La contraseña no es correcta. // Se graba este intento en la base de datos.
$now = time();
$mysqli->query("INSERT INTO login_attempts(user_id, time)
VALUES ('$user_id', '$now ')");
return false;
}
}
} else {
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 8/21
// El usuario no existe.
return false;
}
}
}
3 La función de fuerza bruta.
Los ataques de fuerza bruta se dan cuando un hacker intenta acceder a una
cuenta con 1000 contraseñas diferentes, ya sean generadas al azar o de un diccionario.
En nuestra secuencia de comandos, si la cuenta de un usuario no inicia la sesión
después de más de 5 intentos, su cuenta se bloqueará.
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.
Recomendamos enfáticamente usar un CAPTCHA. Como no hemos implementado esta
funcionalidad en nuestro código ejemplo, esperamos hacerlo próximamente con
SecureImage, ya que no requiere inscripción. Podrías preferir algo más conocido como
reCAPTCHA de Google.
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”:
function checkbrute($user_id, $mysqli) {
// Obtiene el timestamp del tiempo actual.
$now = time();
// Todos los intentos de inicio de sesión se cuentan desde las 2 horas anteriores.
$valid_attempts = $now - (2 * 60 * 60);
if ($stmt = $mysqli->prepare("SELECT time
FROM login_attempts
WHERE user_id = ?
AND time > '$valid_attempts'")) {
$stmt->bind_param ('i', $user_id);
// Ejecuta la consulta preparada.
$stmt->execute();
$stmt->store_result();
// Si ha habido más de 5 intentos de inicio de sesión fallidos.
if ($stmt->num_rows > 5) {
return true;
} else {
return false;
}
}
}
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 9/21
4 Revisa el estado de la sesión iniciada.
Lo haremos mediante la comprobación de “user_id” y las variables de sesión
“login_string”. La variable SESSION “login_string” tiene la información del navegador de
los usuarios junto con la contraseña unida mediante una función hash. Utilizamos la
información del navegador, ya que es muy poco probable que el usuario lo vaya a
cambiar a la mitad de la sesión. Hacerlo ayudará a prevenir un robo de sesión. Agrega
esta función a tu archivo “functions.php” en la carpeta “includes de tu aplicación:
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'];
// Obtiene la cadena de agente de usuario del usuario.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
if ($stmt = $mysqli->prepare("SELECT password
FROM members
WHERE id = ? LIMIT 1")) {
// Une “$user_id” al parámetro. $stmt->bind_param ('i', $user_id);
$stmt->execute(); // Ejecuta la consulta preparada.
$stmt->store_result();
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 Sanea la URL de PHP_SELF
Esta función sanea la salida de la variable del servidor PHP_SELF. Es una
modificación de una función del mismo nombre usada por el sistema de gestión de
contenido WordPress:
function esc_url($url) {
if ('' == $url) {
return $url;
}
$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i' , '',
$strip = array('%0d', '%0a', '%0D', '%0A');
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 10/21
$url = (string) $url;
$count = 1;
while ($count) {
$url = str_replace($strip, '', $url, $count);
}
$url = str_replace(';//', '://', $url);
$url = htmlentities($url);
$url = str_replace('&', '&', $url);
$url = str_replace("'", ''', $url);
if ($url[0] !== '/') {
// Solo nos interesan los enlaces relativos de $_SERVER['PHP_SELF']
return '';
} else {
return $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.
Anuncio
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';
sec_session_start(); // Nuestra manera personalizada segura de iniciar sesión PHP.
if (isset($_POST['email'], $_POST['p'])) {
$email = $_POST['email'];
$password = $_POST['p']; // La contraseña con hash
Parte 5 de 8: Crear páginas de procesamiento
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 11/21
if (login($email, $password, $mysqli) == true) {
// Inicio de sesión exitosa
header('Location: ../protected_page.php');
} else {
// Inicio de sesión exitosa
header('Location: ../index.php?error=1');
}
} else {
// Las variables POST correctas no se enviaron a esta página.
echo 'Solicitud no válida';
}
2 Crea una secuencia de comandos para cerrar sesión.
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();
// Desconfigura todos los valores de sesión.
$_SESSION = array();
// Obtiene los parámetros de sesión.
$params = session_get_cookie_params();
// Borra el cookie actual.
setcookie(session_name(),
'', time() - 42000,
$params["path"],
$params["domain"],
$params["secure"],
$params["httponly"]);
// Destruye sesión.
session_destroy();
header('Location: ../ index.php');
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 aque 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:
Obtiene y valida el nombre de usuario que el usuario desea adoptar.
Obtiene y valida la dirección de correo electrónico del usuario.
Obtiene y valida la contraseña que el usuario desea usar.
Pone la contraseña con hash y la devuelve a la página “register.php” (o sea, la
envía a sí misma).
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 12/21
<?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
<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 m
<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.
</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" /><b
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>
El archivo “register.inc.php” en el directorio “includes” deberá tener el código a
continuación:
<?php
include_once 'db_connect.php';
include_once 'psl-config.php';
$error_msg = "";
if (isset($_POST['username'], $_POST['email'], $_POST['p'])) {
// Sanear y validar los datos provistos.
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 13/21
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// No es un correo electrónico válido.
$error_msg .= '<p class="error">The email address you entered is not va
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
// La contraseña con hash deberá ser de 128 caracteres.
// De lo contrario, algo muy raro habrá sucedido.
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
// La validez del nombre de usuario y de la contraseña ha sido verificada en el cliente.
// Esto será suficiente, ya que nadie se beneficiará de
// violar estas reglas.
//
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// Verifica el correo electrónico existente.
if ($stmt) {
$stmt->bind_param ('s', $email);
$stmt->execute();
$stmt->store_result();
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 alre$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
// Verifica el nombre de usuario existente.
$prep_stmt = "SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
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 userna
$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)
// Crea una contraseña con sal.
$password = hash('sha512', $password . $random_salt);
// Inserta el nuevo usuario a la base de datos.
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, ema$insert_stmt->bind_param ('ssss', $username, $email, $password, $ran
// Ejecuta la consulta preparada.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT
}
}
header('Location: ./register_success.php');
}
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 14/21
}
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.
Anuncio
1 Crea el archivo “sha512.js”.
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.
Podrás descargar el archivo de pajhome.org.uk
(también se guardará en el repositorio de github).
Guarda tu copia de este archivo en un directorio titulado “js” en el directorio de raíz de la
aplicación.
2 Crea el archivo “forms.js”.
Este archivo, el cual deberás crear en el directorio “js”de la aplicación, se
encargará del hash de las contraseñas para los formularios de inicio de sesión
(formhash()) y de registro (regformhash()):
function formhash(form , password) {
// Crea una entrada de elemento nuevo, esta será nuestro campo de contraseña con hash.
var p = document.createElement("input");
// Agrega el elemento nuevo a nuestro formulario.
Parte 6 de 8: Crear archivos de Javascript
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 15/21
form.appendChild(p);
p.name = "p";
p.type = "hidden";
p.value = hex_sha512(password.value);
// Asegúrate de que la contraseña en texto simple no se envíe.
password.value = "";
// Finalmente envía el formulario.
form.submit();
}
function regformhash(form , uid, email, password, conf) {
// Verifica que cada campo tenga un valor
if (uid.value == '' ||
email.value == '' ||
password.value == '' ||
conf.value == '') {
alert('Deberá brindar toda la información solicitada. Por favor, intent
return false;
}
// Verifica el nombre de usuario
re = /^\w+$/ ;
if(!re.test(form.username.value)) {
alert("El nombre de usuario deberá contener solo letras, números y guio
form.username.focus(); return false;
}
// Verifica que la contraseña tenga la extensión correcta (mín. 6 caracteres)
// La verificación se duplica a continuación, pero se incluye para que el
// usuario tenga una guía más específica.
if (password.value.length < 6) {
alert('La contraseña deberá tener al menos 6 caracteres. Por favor, int
form.password.focus();
return false;
}
// Por lo menos un número, una letra minúscula y una mayúscula
// Al menos 6 caracteres
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 m
return false;
}
// Verifica que la contraseña y la confirmación sean iguales
if (password.value != conf.value) {
alert('La contraseña y la confirmación no coinciden. Por favor, inténte
form.password.focus();
return false;
}
// Crea una entrada de elemento nuevo, esta será nuestro campo de contraseña con hash.
var p = document.createElement("input");
// Agrega el elemento nuevo a nuestro formulario.
form.appendChild(p);
p.name = "p";
p.type = "hidden";
p.value = hex_sha512(password.value);
// Asegúrate de que la contraseña en texto simple no se envíe.
password.value = "";
conf.value = "";
// Finalmente envía el formulario.
form.submit(); return true;
}
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.
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 16/21
Anuncio
1 Crea el formulario de inicio de sesión (login.php).
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_for
Correo electrónico: <input type="text" name="email" />
Parte 7 de 8: Crear páginas HTML
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 17/21
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.
<p> Si ha terminado, por favor<a href="includes/logout.php">cierre la s
<p>Está conectado.<?php echo $logged ?>.</p>
</body>
</html>
2 Crea la página “register_success.php.
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 se
</body>
</html>
3 Crea la página de error.
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>
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 18/21
<p class="error"><?php echo $error; ?></p>
</body>
</html>
Anuncio
1 Secuencia de comandos para la protección de páginas.
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.
// Agrega la conexión y las funciones de la base de datos aquí. Ver 3.1.
sec_session_start();
if(login_check($mysqli) == true) {
// ¡Agrega el contenido de tu página protegida aquí!
} else { echo “No está autorizado para acceder a esta página. Por favor, inicie
}
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>
Este es un ejemplo de página protegida. Para acceder a esta pá
deberán iniciar su sesión. En algún momento, también verificar
del usuario para que las páginas puedan determinar el tipo de u
autorizado para acceder a la página.
</p>
<p>Regresar a la<a href="index.php">página de inicio de sesión.</a>
<?php else : ?>
<p>
<span class="error">No está autorizado para acceder a esta pági
Parte 8 de 8: Proteger páginas
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 19/21
</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.
Anuncio
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.
Anuncio
Consejos
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 20/21
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 cualpodrí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 veasque escribes mejores aplicaciones.
http://crackstation.net/hashing-security.htm Hash de contraseña
https://www.owasp.org/index.php/SQL_Injection Información sobre
inyección SQL
Categorías: Computadoras y electrónica
Otros idiomas:
English: Create a Secure Login Script in PHP and MySQL, Português: Criar um Script
de Login Seguro em PHP e MySQL, Italiano: Creare uno Script Sicuro per il Login
Usando PHP e MySQL, Deutsch: Ein sicheres Login Skript mit PHP und MySQL
erstellen, Français: créer un script de connexion sécurisée avec PHP et
MySQL, !"##$%&: #'()*+, -.('/*#01& 2'3%0 #$4%/+ 5 PHP % MySQL, Bahasa
Advertencias
Referencias
Acerca del artículo
7/24/2019 segura en mysql php
http://slidepdf.com/reader/full/segura-en-mysql-php 21/21
Esta página se ha visitado 106 753 veces.
Indonesia: Membuat Skrip Log Masuk yang Aman di PHP dan MySQL