mysql_real_escape_string

(PHP 4 >= 4.3.0, PHP 5)

mysql_real_escape_string --  Escapa caracteres especiales de una cadena para su uso en una sentencia SQL

Descripción

string mysql_real_escape_string ( string cadena_no_escapada [, resource id_enlace] )

cadena_no_escapada

La cadena a escapar

id_enlace (opcional)

El recurso de conexión mysql

Esta función escapará todos los caracteres especiales en la cadena_no_escapada, tomando en cuenta el juego de caracteres actual de la conexión, de tal modo que sea seguro usarla con mysql_query(). Si desea insertar datos binarios, debe usar ésta función.

mysql_real_escape_string() llama a la función de la biblioteca MySQL mysql_escape_string, la cual coloca barras invertidas antes de los siguientes caracteres: NULL, \x00, \n, \r, \, ', " y \x1a.

Ejemplo 1. Ejemplo sencillo de mysql_real_escape_string()

<?php
// Conectarse
$enlace = mysql_connect('mysql_host', 'mysql_usuario', 'mysql_contrasenya')
    OR die(
mysql_error());

// Consulta
$query = sprintf("SELECT * FROM usuarios WHERE usuario='%s' AND
     password='%s'"
,
            
mysql_real_escape_string($usuario),
            
mysql_real_escape_string($password));
?>

Es necesario usar siempre (con algunas excepciones) esta función para asegurarse de que los datos sean seguros antes de enviar una consulta a MySQL. Si tiene habilitada la directiva magic_quotes_gpc, y está trabajando con datos que provienen del usuario, debe usar stripslashes() primero sobre sus datos. Si sus datos provienen de otras fuentes y tiene habilitada la directiva magic_quotes_runtime, deberá también usar stripslashes() con sus datos. De no ser así, quedará abierto a ataques de inyección SQL. He aquí un ejemplo:

Ejemplo 2. Un ejemplo de un ataque de inyección SQL

<?php
// Consultar la base de datos para verificar si hay una coincidencia de usuario
$consulta = "SELECT * FROM usuarios WHERE usuario='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($consulta);

// No revisamos $_POST['password'], podria ser cualquier cosa que el usuario
// quiera! Por ejemplo:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR 1=1";

// Esto quiere decir que la consulta enviada a MySQL seria:
echo $consulta;
?>

La consulta enviada a MySQL:

SELECT * FROM usuarios WHERE usuario='aidan' AND password='' OR 1=1

¡Esto permitiría que cualquiera iniciara una sesión sin una contraseña válida! Usando mysql_real_escape_string() con cada variable se previene esto.

<?php
/**
* Aplicar comillas sobre una variable para hacerla segura
*/
function comillas_inteligentes($valor)
{
    
// Retirar las barras si es necesario
    
if (get_magic_quotes_gpc()) {
        
$valor = stripslashes($valor);
    }

    
// Colocar comillas si no es un entero
    
if (!is_int($valor)) {
        
$valor = "'" . mysql_real_escape_string($valor) . "'";
    }

    return
$valor;
}

// Conexion
$enlace = mysql_connect('mysql_host', 'mysql_usuario', 'mysql_contrasenya')
    OR die(
mysql_error());

// Realizar una consulta segura
$consulta = sprintf("SELECT * FROM usuarios WHERE usuario=%s AND password=%s",
            
comillas_inteligentes($_POST['username']),
            
comillas_inteligentes($_POST['password']));

mysql_query($consulta);
?>

La consulta será ejecutada correctamente ahora, y los ataques de inyección no darán resultado.

Nota: mysql_real_escape_string() no escapa % ni _. Éstos son comodines en MySQL si se combianan con LIKE, GRANT, o REVOKE.

Vea también mysql_client_encoding(), addslashes(), stripslashes(), y las directivas magic_quotes_gpc y magic_quotes_runtime.