Una de las ventajas más grandes de PHP es la facilidad con la cual puede comunicarse con las bases de datos, lo más normal con MySQL.
Mucha gente hace el uso excesivo de esto, y muchos grandes sitios, confía en las bases de datos para funcionar.
Sin embargo, con esa ventaja hay problemas suficientemente grandes en la seguridad a los que tendras que hacer frente. Afortunadamente, hay un montón de soluciones. El peligro más común de seguridad al que debes de hacer frente es cuando un usuario utiliza un fallo para poder atacar directamente al servidor de bases de datos con sentencias SQL.
Utilicemos un ejemplo común. Muchos sistemas utilizan un codigo muy parecido a este para comprobar el usuario y la contraseña pudiendose hacer todas las combinaciones válidas del usuario y de su contraseña, por ejemplo para controlar el acceso a un área de administración:
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$_POST['username']."' and Password = '".$_POST['password']."'");
¿Te parece familiar?. Y parece que no podría hacer mucho daño. Pero digamos por un momento que introduzco el siguiente usuario en el formulario:
'O 1=1 #
La pregunta que va a ser ejecutada sería esta:
SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''
La almohadilla (#) le dice aMySQL que todo que le sigue es un comentario y que no debe de hacerle caso. Ejecutará SQL hasta ese punto. Despues 1 es igual a 1, SQL devolverá todos los usuarios y contraseñas de la base de datos. Y como la primera combinación del usuario y de contraseña en la mayoría de las bases de datos es la de el administrador, la persona que incorporó simplemente algunos símbolos en un formulario ahora entra como administrador de la Web , con los mismos privilegios que tendría si supiera realmente el usuario y la contraseña.
Con una poca de creatividad, este agujero de seguridad se puede explotar aun más lejos, permitiendo que un usuario cree su propia cuenta , lea números de las tarjetas de crédito o simplemente vacie la base de datos.
Afortunadamente, este tipo de vulnerabilidad es bastante fácil de solucionar. Comprobando si hay algun caracter raro cuando el usuario introduce los datos, y quitándolos o neutralizandos, podemos evitar que cualquier persona utilize su propio código del SQL en nuestra base de datos. La función que sigue sería la adecuada:
function make_safe($variable) {
$variable = addslashes(trim($variable));
return $variable;
}
Ahora debemos modificar nuestra consulta. En vez de usar variables _POST como en la consulta de arriba, ahora utilizamos todos los datos del usuario con la función make_safe, dando por resultado el código siguiente:
$username = make_safe($_POST['username']);
$password = make_safe($_POST['password']);
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$username."' and Password = '".$password."'");
Ahora, si un usuario incorporó los datos anteriormente citados, la consulta será la siguiente, que es totalmente inofensiva. La consulta siguiente seleccionará de una base de datos los registros donde el usuario es igual a \ 'O o 1=1 #.
SELECT Username, Password, UserLevel FROM Users WHERE Username = '\' OR 1=1 #' and Password = ''
Ahora, a menos que tengas un usuario con un nombre muy inusual y una contraseña en blanco, tu malévolo atacante no podrá hacer ningún daño en tu sitio Web. Es importante comprobar todos los datos pasados a tu base de datos. Las cabeceras de HTTP enviados por elusuario pueden ser falsificadas. Su dirección de remitente tambien puede ser falsificada. No confies en los datos enviados por el usuario, y tu y tu sitio estareis a salvo.
Manu Gutierrez