Seguridad con PHP / MySQL

1Sebastian Barria6th Mar 2010MySQL, PHP, Seguridad, Web

Al montar un servidor o programar un sitio web basado en PHP y MySQL, hay que tener en consideración algunos conceptos de seguridad. En esta ocasión, hablaré de 3 problemas de seguridad básicos:

  • Los usuarios y sus privilegios (en MySQL)
  • La configuración de apache
  • El filtrado de formularios y URL’s

Este post está enfocado, principalmente, a quienes pretenden montar un servidor en su computador (localhost) pues, por lo menos en los servidores pagados, la seguridad con los privilegios de MySQL está implementada.

Los problemas de seguridad

Los usuarios y sus privilegios (en MySQL)

El principal problema de montar un servidor en casa (localhost), es que los software que se utilizan para esto – EasyPHP, Appserv, etc – vienen con usuarios por defecto… el famoso “_root” sin contraseña. Esto implica que cualquier persona con un poco de conocimientos de hackeo, pueda botar la base de datos u obtener información de ella si es que el usuario por defecto no se cambia (ya que el hacker sabría que el nombre de usuario es “_root” y no tiene contraseña).

La configuración de apache

Además de eso, está el problema de configuración de apache, pues appserv, por ejemplo, establece todas las variables como globales por defecto (por ejemplo, si recibo una variable por el metodo “POST”, simplemente escribo “echo $nombre_de_la_variable” para mostrarla en pantalla). Si bien las variables globales son más cómodas, implican riesgos en seguridad y confusión, porque si se necesita recibir la variable “admin_pass” por el método POST y el “hacker” escribe una url como “…index.php?admin_pass=miclave“, se estaría recibiendo la variable por otro método y poniendo en riesgo la seguridad del sitio.

El filtrado de formularios y URL’s

Otro problema es la seguridad con PHP, pues si no se filtra la información recibida a través de formularios o de la URL, se esta dando pie para que gente mal intencionada ejecute scripts que pongan en riesgo la seguridad de nuestro sitio.

Las soluciones

Antes que nada, se debe definir el software a utilizar. Por mi parte, y por conceptos de seguridad, yo recomiendo EasyPHP, pues es mucho mas “paranoico” que Appserv, y viene mucho más limitado en conceptos de seguridad y mensajes de error; es decir, que viene “mejor configurado” (en conceptos de seguridad) por defecto, y no hay que preocuparse de cambiar muchas cosas.

Por esto, la siguiente solución la veremos específicamente para EasyPHP (aunque también se aplica para Appserv).

Los usuarios y sus privilegios (en MySQL)

Lo primero que se debería hacer, al montar un servidor en casa, es definir un usuario que tenga todos los privilegios necesarios para administrar nuestro sitio.

Para esto, hay que realizar las siguientes operaciones:

  1. Ir a PhpMyAdmin (la administración de MySQL) y crear un nuevo usuario (o modificar “_root”) con un username y un password que no sea tan obvio.
  2. Abrir el archivo de configuración llamado “config.inc.php” (ubicado en …EasyPHP1-8\phpmyadmin\), las variables $cfg['Servers'][$i]['user'] = ‘_root’; y $cfg['Servers'][$i]['password'] = ”;, y poner ahí el username y password definido para el administrador de MySQL en el paso anterior.
  3. Eliminar el usuario “_root” (en el caso de haber creado otro usuario para la administración), pues si se deja, el sitio seguirá siendo inseguro.

A partir de este punto, si se quiere, se puede crear otro usuario con menos privilegios (por ejemplo que no pueda crear o eliminar tablas), que sea con el que nos conectemos desde el sitio y, de esta manera, correr menos riesgos.

La configuración de apache

El tema de la configuración pasa, primero, por elegir el servidor adecuado. En el caso de EasyPHP, la configuración por defecto es bastante buena si hablamos de seguridad, pero hay que fijarse bien (a la hora de programar) en solucionar todos los errores y en los mensajes de error que devuelve, pues aveces dice “imposible conectar a la base de datos MiBase”, por lo que estaríamos entregando información privada el importante.

Hay otros conceptos que son más técnicos (y que no serán abordados en este post), como la cantidad de usuarios máximos conectados a la base de datos, y que hacer cuando se sobrepasan los límites; los tamaños de los archivos que se pueden subir; los privilegios de las carpetas, etc que se deben tener en cuenta a la hora de configurar el servidor.

El filtrado de formularios y URL’s

Personalmente, he ido creando mis propias funciones de seguridad para filtrar las entradas por cookies, formularios, y los métodos GET y POST.

Las funciones, las almaceno en un archivo validar.php y luego, simplemente, las inserto al principio de cada uno de mis archivos donde necesite validar variables (a través del comando include(“validar.php”);).

La manera de utilizarlas, es definiendo las variables de la manera:

$mi_variable=varpost("nombre_de_la_variable_a_recibir" , "valor en caso de no encontrarse la variable" , largo en caracteres);

Después de eso, solo queda utilizar $mi_variable en mi archivo php. Esto asegura que la variable quedará definida (y no aparecerán mensajes de error por variables no definidas). También asegura recibir la variable por el método especificado (y no por otro) y definirle un tamaño máximo (para no recibir, por ejemplo, mensajes de 12404502345023 caracteres).

Las funciones son las siguientes:

function validar( $variable, $tam ){
 $va=htmlentities($variable,ENT_QUOTES,"UTF-8");
 mysql_escape_string($va);
 $va=substr ($va, 0, $tam);
 return $va;
}

function varget($valor, $vacio, $tam){
 if (empty($_GET[$valor])) { $res=$vacio; }
 else { $res=validar($_GET[$valor],$tam); }
 return $res;
}

function varpost($valor, $vacio, $tam){
 if (empty($_POST[$valor])) { $res=$vacio; }
 else { $res=validar($_POST[$valor],$tam); }
 return $res;
}

function varcookie($valor, $vacio, $tam){
 if (empty($_COOKIE[$valor])) { $res=$vacio; }
 else { $res=validar($_COOKIE[$valor],$tam); }
 return $res;
}

function varsess($valor, $vacio, $tam){
 if (empty($_SESSION[$valor])) { $res=$vacio; }
 else { $res=validar($_SESSION[$valor],$tam); }
 return $res;
}

Conclusión

Estas son algunas de las medidas de seguridad básicas para no pasar por inculto a la hora de diseñar un sitio y de montar un servidor casero.

Espero que quien las lea las tome en cuenta, las aproveche; mejoren las funciones de seguridad y las adecuen para satisfacer las necesidades de su sitio.

  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Bitacoras.com
  • Meneame
  • Netvibes
  • StumbleUpon
  • Twitter

Switch to our mobile site