¿Debo mysql_real_escape_string todas las cookies que recibo del usuario para evitar la inyección de mysql en php?

StackOverflow https://stackoverflow.com/questions/90517

  •  01-07-2019
  •  | 
  •  

Pregunta

Cuando un usuario visita mi sitio, mi secuencia de comandos busca 2 cookies que almacenan la identificación del usuario + parte de la contraseña, para iniciar sesión automáticamente.

Es posible editar el contenido de las cookies a través de un editor de cookies, así que supongo que es posible agregar contenido malicioso a una cookie escrita.

¿Debo agregar? mysql_real_escape_string (u otra cosa) a todas mis llamadas de cookies o ¿hay algún tipo de procedimiento integrado que no permitirá que esto suceda?

¿Fue útil?

Solución

Lo que tu en realidad Lo que hay que hacer es, en primer lugar, no enviar estos valores de cookies que se pueden piratear.En cambio, ¿por qué no codificar el nombre de usuario, la contraseña y una sal (secreta) y establecerlo como valor de la cookie?es decir.:

define('COOKIE_SALT', 'secretblahblahlkdsfklj');
$cookie_value = sha1($username.$password.COOKIE_SALT);

Entonces sabrá que el valor de la cookie siempre será una cadena hexadecimal de 40 caracteres y podrá comparar el valor que el usuario envía con lo que esté en la base de datos para decidir si son válidos o no:

if ($user_cookie_value == sha1($username_from_db.$password_drom_db.COOKIE_SALT)) {
  # valid
} else {
  #not valid
}

mysql_real_escape_string hace un impacto adicional a la base de datos, por cierto (mucha gente no se da cuenta de que requiere una conexión a la base de datos y consulta MySQL).

La mejor manera de hacer lo que quiere si no puede cambiar su aplicación e insiste en usar valores de cookies pirateables es usar declaraciones preparadas con parámetros vinculados.

Otros consejos

El objetivo de mysql_real_escape_string no es proteger contra ataques de inyección, sino garantizar que sus datos se almacenen con precisión en la base de datos.Por lo tanto, se debe invocar en CUALQUIER cadena que ingrese a la base de datos, independientemente de su fuente.

Deberías, sin embargo, también Utilice consultas parametrizadas (a través de mysqli o PDO) para protegerse de la inyección de SQL.De lo contrario corres el riesgo de terminar como La pequeña escuela de Bobby Tables.

Sólo uso mysql_real_escape_string antes de insertar variables en una declaración SQL.Te confundirás si algunas de tus variables son ya escapaste, y luego vuelves a escapar de ellos.Es un error clásico que se ve en las aplicaciones web de blogs de novatos:

Cuando alguien escribe un apóstrofe, sigue agregando barras diagonales arruinando las páginas del blog\\\\\\\.

El valor de una variable no es peligroso por sí solo:Sólo cuando lo pones en una cuerda o algo similar comienzas a desviarte hacia aguas peligrosas.

Por supuesto, nunca confíes en nada que provenga del lado del cliente.

Las declaraciones preparadas y la vinculación de parámetros siempre son un buen camino a seguir.

PEAR::MDB2 admite declaraciones preparadas, por ejemplo:

$db = MDB2::factory( $dsn );

$types = array( 'integer', 'text' );
$sth = $db->prepare( "INSERT INTO table (ID,Text) (?,?)", $types );
if( PEAR::isError( $sth ) ) die( $sth->getMessage() );

$data = array( 5, 'some text' );
$result = $sth->execute( $data );
$sth->free();
if( PEAR::isError( $result ) ) die( $result->getMessage() );

Esto solo permitirá que los datos adecuados y una cantidad preestablecida de variables ingresen a la base de datos.

Por supuesto, debes validar los datos antes de llegar tan lejos, pero preparar declaraciones es la validación final que se debe hacer.

Deberías mysql_real_escape_string cualquier cosa eso podría ser potencialmente dañino.Nunca confíes en ningún tipo de entrada que pueda ser alterada por el usuario.

Estoy de acuerdo con usted.Es posible modificar las cookies y enviar datos maliciosos.

Creo que es una buena práctica filtrar los valores que obtienes de las cookies antes de utilizarlas.Como regla general, filtro cualquier otra entrada que pueda ser manipulada.

Yegor, puede almacenar el hash cuando se crea/actualiza una cuenta de usuario, luego, cada vez que se inicia un inicio de sesión, realiza un hash de los datos publicados en el servidor y los compara con lo que se almacenó en la base de datos para ese nombre de usuario.

(Fuera de mi cabeza en php suelto; trátelo como pseudocódigo):

$usernameFromPostDbsafe = LimitToAlphaNumUnderscore($usernameFromPost);
$result = Query("SELECT hash FROM userTable WHERE username='$usernameFromPostDbsafe' LIMIT 1;");
$hashFromDb = $result['hash'];
if( (sha1($usernameFromPost.$passwordFromPost.SALT)) == $hashFromDb ){
    //Auth Success
}else{
   //Auth Failure
}

Después de una autenticación exitosa, puede almacenar el hash en $_SESSION o en una tabla de base de datos de nombres de usuario/hashes autenticados en caché.Luego, envíe el hash de regreso al navegador (en una cookie, por ejemplo), para que las cargas posteriores de la página envíen el hash de regreso al servidor para compararlo con el hash almacenado en el almacenamiento de sesión elegido.

mysql_real_escape_string está tan pasado de moda...Hoy en día deberías utilizar el enlace de parámetros.

Explicaré más detalladamente que me refería a declaraciones preparadas y proporcione un enlace a un artículo que demuestra que a veces mysl_real_escape_string no es suficiente: http://www.webappsec.org/projects/articles/091007.txt

Recomendaría usar htmlentities($input, ENT_QUOTES) en lugar de mysql_real_escape_string ya que esto también evitará cualquier salida accidental de código HTML real.Por supuesto, podrías usar mysql_real_escape_string y htmlentities, pero ¿por qué lo harías?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top