PHP para iniciados en la programación (XIII), seguridad en los programas.

tutorial PHP para iniciados en la programacion

 

 

Posibles amenazas de seguridad

Básicamente son dos grupos de personas que pueden atacar su sistema.

  • Hackers: con la intención de obtener acceso a datos no autorizados o interrumpir la aplicación
  • Usuarios: pueden ingresar inocentemente parámetros incorrectos en formularios que pueden tener efectos negativos en un sitio web o aplicación web.

Los siguientes son los tipos de ataques que debemos tener en cuenta.

Inyección SQL : este tipo de ataque agrega código dañino a las declaraciones SQL .

Esto se realiza utilizando formularios de entrada de usuario o URL que utilizan variables.

El código adjunto comenta la condición en la cláusula WHERE de una instrucción SQL. El código adjunto también puede;

  • insertar una condición que siempre será verdadera
  • eliminar datos de una tabla
  • actualizar datos en una tabla
  • Este tipo de ataque generalmente se usa para obtener acceso no autorizado a una aplicación.

Cross-site scripting: este tipo de ataque inserta código dañino, generalmente JavaScript. Esto se realiza mediante formularios de entrada del usuario, como los formularios de contacto y comentarios. Esto se hace para;

  • Recuperar información confidencial, como datos de cookies.
  • Redireccionar al usuario a una URL diferente.
  • Otras amenazas pueden incluir: inyección de código PHP, inyección de shell, inyección de correo electrónico, divulgación de código fuente de script, etc.

 

Mejores prácticas de seguridad de aplicaciones PHP

Veamos ahora algunas de las mejores prácticas de seguridad de PHP que debemos tener en cuenta al desarrollar nuestras aplicaciones.

 

PHP strip_tags

strip_tags elimina las etiquetas HTML, JavaScript o PHP de una cadena.

Esta función es útil cuando tenemos que proteger nuestra aplicación contra ataques como los scripts de sitios cruzados.

Consideremos una aplicación que acepta comentarios de los usuarios.

<?php
$user_input = "Your site rocks";
echo "<h4>My Commenting System</h4>";
echo $user_input;
?>

 

Suponiendo que ha guardado comments.php en la carpeta phptuts, vaya a la URL http: //localhost/phptut/comments.php y vea el resultado obtenido.

 

Supongamos que recibe lo siguiente : <script>alert(‘Your site sucks!’);</script>

<?php
$user_input = "<script>alert('Your site sucks!');</script>";
echo "<h4>My Commenting System</h4>";
echo $user_input;
?>

Navegue a la URL http: //localhost/phptut/comments.php

 

Ahora aseguremos nuestra aplicación de tales ataques usando la función strip_tags.

<?php
$user_input = "<script>alert('Your site sucks!');</script>";
echo strip_tags($user_input);
?>

 

Navegue a la URL http: //localhost/phptuts/comments.php

 


 

Filtros de saneamiento y de validación en PHP

Los filtros de saneamiento se utilizan para  limpiar las entradas del usuario. Aqui te dejo unos ejemplos de los filtros existentes actualmente:

FILTER_SANITIZE_EMAIL

Elimina todos los caracteres excepto letras, dígitos and !#$%&’*+-/=?^_`{|}~@.[]

FILTER_SANITIZE_ENCODED

Cadena de codificación de URL, opcionalmente tira o codifica caracteres especiales.

FILTER_SANITIZE_NUMBER_FLOAT

Elimina todos los caracteres excepto los dígitos, + – y opcionalmente., eE

FILTER_SANITIZE_NUMBER_INT

Elimina todos los caracteres excepto los dígitos, el signo más (+) y el signo menos (-).

FILTER_SANITIZE_SPECIAL_CHARS

HTML-escape ‘»<>& and characters with ASCII value less than 32, optionally strip or encode other special characters.

FILTER_SANITIZE_STRING

Elimina etiquetas, opcionalmente elimina o codifiqua caracteres especiales.

FILTER_SANITIZE_STRIPPED

Alias de «string» filter.

FILTER_SANITIZE_URL

Elimina todos los caracteres excepto los dígitos, letters, digits and $-_.+!*'(),{}|\\^~[]`<>#%»;/?:@&=

 

Los filtros de validación se utilizan para  validar el tipo de las entradas del usuario. Aqui te dejo unos ejemplos:

FILTER_VALIDATE_BOOLEAN

Devuelve TRUE para ‘1’, ‘true’, ‘on’ y ‘yes’. Devuelve FALSO de lo contrario.

FILTER_VALIDATE_EMAIL

Valida  e-mail.

FILTER_VALIDATE_FLOAT

Valida  float.

FILTER_VALIDATE_INT

Valida el valor como entero opcionalmente del rango especificado.

FILTER_VALIDATE_IP

Valida el valor como dirección IP, opcionalmente solo IPv4 o IPv6 o no de rangos privados o reservados.

FILTER_VALIDATE_REGEXP

Validates value agValida el valor contra regexp, una expresión regular compatible con Perl.

FILTER_VALIDATE_URL

Valida URL

 

filter_var()

PHP5 trae una función que permite comprobar las variables, filter_var(). De esta manera, no tendremos que crear otra vez esas complicadas funciones para comprobar que el parámetro pasado cumpla todas las características que queramos.

Con la función filter_list(), tenemos un listado de todos los filtros soportados: existen filtros de validación, y otros de saneamiento.

Vamos con un ejemplo

Utiliza la función filter_var y la constante FILTER_SANITIZE_STRIPPED para eliminar las etiquetas recibidas desde un input:

<?php
$user_input = "<script>alert('Your site sucks!');</script>";
echo filter_var($user_input, FILTER_SANITIZE_STRIPPED);
?>

Salida:

alert ('¡Your site sucks!');

 

Mysql_real_escape_string

Se utiliza para proteger una aplicación contra la inyección de SQL.

Supongamos que tenemos la siguiente instrucción SQL para validar el ID de usuario y la contraseña.

<?php
SELECT uid,pwd,role FROM users WHERE uid = 'admin' AND password = 'pass';
?>

Un usuario malintencionado puede ingresar el siguiente código en el cuadro de texto de identificación del usuario. ‘OR 1 = 1 – Y 1234 en el cuadro de texto de contraseña Codifiquemos el módulo de autenticación

<?php
$uid = "' OR 1 = 1 -- ";
$pwd = "1234";
$sql = "SELECT uid,pwd,role FROM users WHERE uid = '$uid' AND password = '$pwd';";
echo $sql;
?>

El resultado final será

SELECT uid,pwd,role FROM users WHERE uid = '' OR 1 = 1 -- ' AND password = '1234';

AQUÍ,

  • «SELECT * FROM users WHERE user_id = »» prueba una identificación de usuario vacía
  • «‘OR 1 = 1» es una condición que siempre será verdadera
  • “-» comenta esa parte que prueba la contraseña.

La consulta anterior devolverá a todos los usuarios. Ahora usemos la función mysql_real_escape_string para asegurar nuestro módulo de inicio de sesión.

<?php
$uid = mysql_real_escape_string("' OR 1 = 1 -- ");
$pwd = mysql_real_escape_string("1234");
$sql = "SELECT uid,pwd,role FROM users WHERE uid = '$uid' AND password = '$pwd';";
echo $sql;
?>

El código anterior saldrá

SELECT uid,pwd,role FROM users WHERE uid = '\' OR 1 = 1 -- ' AND password = '1234';

Tenga en cuenta quela segunda cita simple se nos ha escapado, se tratará como parte de la identificación del usuario y no se comentará la contraseña.

 

Md5 y sha1

Md5 es el acrónimo de Message Digest 5 y sha1 es el acrónimo de Secure Hash Algorithm 1.

Ambos se utilizan para cifrar cadenas.

Una vez que se ha cifrado una cadena, es tedioso descifrarla.

Md5 y sha1 son muy útiles al almacenar contraseñas en la base de datos.

El siguiente código muestra la implementación de md5 y sha1

<?php
echo "MD5 Hash: " . md5("password");
echo "SHA1 Hash: " . sha1("password");
?>

 

Suponiendo que ha guardado el archivo hashes.php en la carpeta phptuts, busque la URL

Como puede ver en los hashes anteriores, si un atacante obtuviera acceso a su base de datos, aún no sabría las contraseñas para iniciar sesión.

 

password_hash

Otra forma, y quizas una de las mejores, es el uso de la función password_hash(), que crea un nuevo hash de contraseña usando un algoritmo de hash fuerte de único sentido

Imaginemos que recibimos la contraseña elegida por un usuario al registrarse desde un formulario y queremos guardar esa contraseña en la base de datos.

<?php
$password = $_POST['password']; 
$hash_password   =   password_hash ( $password ,   PASSWORD_DEFAULT ) ; 
echo $hash_password;
?>

PASSWORD_DEFAULT –  Observe que esta constante está diseñada para cambiar siempre que se añada un algoritmo nuevo y más fuerte a PHP. Por esta razón, la longitud del resultado de usar este identificador puede cambiar con el tiempo. Por lo tanto, se recomienda almacenar el resultado en una columna de una base de datos que pueda apliarse a más de 60 caracteres (255 caracteres sería una buena elección).

El password que se guardará para ese usuario es:

$2y$10$8YbwF7zn4OdRi7jo1IeRRuy3Hamc2rq7LHXeQfdq9rUdlUy8whYgu

 

 

Para poder comprobar, a la hora del login, si la contraseña introducida es correcta, se utiliza la funcion password_verify(). A esta función le pasamos el hash creado anteriormente y guardado en la base de datos junto con el password introducido por el usuario ( en este ejemplo hemos usado ‘myPass_2019$‘)

if (password_verify('myPass_2019$', $hash_password)) {
    echo '¡La contraseña es válida!';
} else {
    echo 'La contraseña no es válida.';
}

 

Compartir esta entrada.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

CAPTCHA ImageChange Image