Primero que nada use lo que se llama como Prepared Statements, que nos permite realizar una consulta al DBMS, pudiendo por asi decirlo, separar lo que ingresa el usuario del codigo mismo, es decir que el motor sabe que valor es ingresado por el usuario, con la ventaja pricipal en seguridad de que no pueden inyectar codigo arbitrario en la consulta conocido como SQL INJECTIO
Coloquemos un ejemplo de lo que seria una consulta con Prepared Statements, un consulta a un articulo de una noticia.
$mysqli = new mysqli('host', 'user', 'pass', 'db');
$stmt=$mysqli->prepare("SELECT * FROM NOTICIAS WHERE ID=?");
$stmt->bind_param('i', $_GET['id']);
$stmt->execute();
En la primer linea creamos el un objeto mysqli, en la segunda preparamos la consulta para enviar al motor, note que el valor que se espera se coloca con el caracter ?, tercera linea agrega la variable a la sentencia preparada, fijese que está el valor i, lo cual significa que lo que se espera será un entero. Tambien podemos usar s (string), d (double), b (binary data) dependiendo lo que se necesita.
En la cuarta linea ejecutamos el Statement Prepared. :)
En la sección de Prevencion de SQL INJECTION de la OWASP, lo tenemos como primer medida de seguridad. Lo bueno de esto es que el codigo no queda tan sucio, al filtrar todas las entradas del usuario con funciones como int(), settype(), is_numeric(), mysql_real_escape_string() etc.
El alta creado tiene las siguientes caracteristicas: La contraseña se encripta 3 veces en md5 (lo cual se puede cambiar desde el codigo), debe ser mayor a 7 caracteres, y debe contener al menos una mayuscula y un numero.
Este es el codigo con el formulario en HTML y el PHP.
<html>
Alta Usuario
<form action='' method='post'>
<br>
Nombre:
<br>
<input type='text' name='nombre'>
<br>
<br>
<input type='text' name='email'>
<br>
Usuario:
<br>
<input type='text' name='user'>
<br>
Contraseña:
<br>
<input type='password' name='pass'>
<br>
<input type='submit' value='Enviar' name='enviar'>
</form>
function pass_cript($pass){
for($i=0;$i <3;$i++){ pass="md5($pass);" stmt=" $mysqli">prepare("SELECT usuario FROM usuarios WHERE usuario=?");
$stmt->bind_param('s', $usuario);
$stmt->execute();
$stmt->bind_result($result);
#tercer if
if($stmt->fetch()== false)
{
verificar_pass();
}
else {
echo "El usuario ya existe";
}
}
function alta(){
global $mysqli;
global $usuario;
global $password;
global $email;
global $nombre;
$password=pass_cript($password);
$stmt=$mysqli->prepare("INSERT INTO usuarios (usuario, password, Email, Nombre) VALUES (?, ?, ?, ?)");
// Bind your variables to replace the ?s
$stmt->bind_param('ssss', $usuario, $password, $email, $nombre);
// Execute query
$stmt->execute();
printf("%d Fila Insertada.\n", $stmt->affected_rows);
// Close statement object
$stmt->close();
echo "El usuario ".$usuario." ha sido dado de alta!!";
}
function verificar_pass(){
global $password;
if(strlen($password) > 7 )
{
if (preg_match('/[A-Z]+[0-9]+/', $password) || preg_match('/[0-9]+[A-Z]+/', $password))
{
alta();
}
else
{
echo "El password debe estar constituido por al menos una mayuscula y al menos un digito";
exit;
}
}
else
{
echo "El password debe ser mayor a 7 caracteres";
}
}
#Prepared Statements
$mysqli = new mysqli('host', 'user', 'pass', 'db');
if (mysqli_connect_errno())
{
printf("Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error());
exit;
}
#Primer if
if(!empty($_POST['enviar']))
{
#segundo if
if (isset($_POST['nombre']) && !empty($_POST['nombre']) && isset($_POST['email']) && !empty($_POST['email']) && isset($_POST['user']) && !empty($_POST['user']) && isset($_POST['pass']) && !empty($_POST['pass']))
{
$nombre=$_POST['nombre'];
$usuario=$_POST['user'];
$password=$_POST['pass'];
$email=$_POST['email'];
verificar_usuario();
}#cierre segundo if
else
{
echo "Debe rellenar los camposs gracias";
}
}#cierro primer if
?>
Voy a explicar lo que hace el codigo, osea su secuencia para que se entienda y luego los que quieren usarlo lo usen para sus
altas XD o para probar.
En la linea 105 es donde verifico que todos los datos del formulario esten definidos y que no esten en blanco, en caso afirmativo
tomo esos valores y voy a la función verificar_usuario().
Esta función lo que hace es verificar si el usuario que se quiere dar de alta existe en la base de datos,
en caso de que llegara a existir imprimira una leyenda con "El usuario ya existe", y se terminaria el proceso. En caso negativo se
se dirige a la función verificar_pass().
Esta función realiza el testeo de seguridad del password donde debe cumplir que: debe ser mayor a 7 caracteres y
debe contener al menos una mayuscula y un numero en el.
Cumpliendo estas restricciones en el password se dirige a la función alta(), que en la linea 57,
el valor de $password es pasado a a la función pass_cript(), para encriptarlo en una cantidad de 3 veces en MD5, luego basicamente
se realiza el INSERT INTO correspondiente al alta :).
Aca les dejo algunos enlaces para que sigan leyendo sobre Prepared Statemen
http://mattbango.com/notebook/web-development/prepared-statements-in-php-and-mysqli/
http://www.ultramegatech.com/blog/2009/07/using-mysql-prepared-statements-in-php/
http://www.hiteshagrawal.com/mysql/mysql-prepared-statement-in-php
Saludos