2011-01-20 11 views
6

Estoy desarrollando un sitio web y estoy intentando asegurar la parte de la conexión.Proteger contra inyección de SQL

Utilicé la función addslashes en $login para detener la inyección de SQL pero algunos amigos me dijeron que no había suficiente seguridad. Sin embargo, no me mostraron cómo aprovechar esta vulnerabilidad.

¿Cómo puedo/puedo romper este código? ¿Cómo puedo protegerlo?

<?php 

    if (isset($_POST) && (!empty($_POST['login'])) && (!empty($_POST['password']))) 
    { 
     extract($_POST); 
     $sql = "SELECT pseudo, sex, city, pwd FROM auth WHERE pseudo = '".addslashes($login)."'"; 
     $req = mysql_query($sql) or die('Erreur SQL'); 
     if (mysql_num_rows($req) > 0) 
     { 
      $data = mysql_fetch_assoc($req); 
      if ($password == $data['pwd']) 
      { 
       $loginOK = true; 
      } 
     } 
    } 
    ?> 
+2

Google addslashes VS mysql_real_escape_string: http://www.sitepoint.com/forums/showthread.php?t=337881 –

+0

Hay muchos tutoriales desactualizados que sugieren 'addslashes()' como un mecanismo para escapar cosas en Consultas SQL. Si está aprendiendo de uno de esos, le sugiero que intente encontrar algo más actualizado y preciso. Además, 'extract ($ _ POST)' es un buen ejemplo de vulnerabilidad; no lo hagas! Por cierto, bienvenido a StackOverflow. –

+0

duplicado casi exacto de http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php – Puddingfox

Respuesta

14

Debe utilizar mysql_real_escape_string para escapar de los parámetros de entrada de cadena en una consulta. Utilice la conversión de tipos para desinfectar los parámetros numéricos y las listas blancas para desinfectar los identificadores.

En la página de PHP referenciada, hay un ejemplo de inyección sql en un formulario de inicio de sesión.

Una mejor solución sería usar declaraciones preparadas, puede hacerlo usando PDO o mysqli.

+0

bien, pero ¿podría darme un ejemplo de inyección SQL para este código? No entiendo cómo puedo romper este código mientras estoy escapando comillas en él. –

+0

@Tom: echa un vistazo [Este artículo sobre el tema] (http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string) – ircmaxell

+0

Un comentario para ese voto negativo sería bueno. – alexn

2

Uso:

mysql_real_escape_string($inputToClean); 
+0

esta función que se llama solo no puede hacer nada mejor que addslashes –

+1

@Col. Metralla: Es un epsilon mejor que 'addslashes' (representaciones Unicode y otras cosas) - pero tienes razón en que un programador que lo usa como un polvo mágico abracadabra-ahora-seguro no es más seguro que con addslashes. – Piskvor

2

Hay otro enorme agujero de seguridad - extract. Puede evitar escribir algunos caracteres, pero abre agujeros demasiado numerosos como para mencionarlos, ya que sobrescribirá cualquier variable global.

¿Qué ocurre si publico esto?

$_POST { 
    'login' => 'Admin', 
    'loginOK' => 1 
} 

Supongo que, $ loginOK es ahora == 1, y voy a iniciar sesión como administrador.

Ahórrese un montón de dolor más tarde, y simplemente use las variables que desea utilizar, en lugar de confiar en el horrible truco que es extract.

+0

Gracias amigo, encontraste otro error. No vi eso. =) –

+0

@ Tom-pouce: De nada. por cierto, eso es ** eeexactly ** el caso contra 'extract' - crea variables" de la nada "(Me ha picado esto y es muy difícil depurarlo). – Piskvor

2

Aparte del uso de addslashes(), estos son algunos temas al azar que se encuentran en este código:

  • isset($_POST) siempre es TRUE, a menos que se ejecuta desde la línea de comandos. Probablemente puedas eliminarlo.
  • empty() es muy complicado. Por ejemplo, si $password = '0' entonces empty($password) es TRUE.
  • Puede hacer esto: if(isset($_POST['login']) && $_POST['login']!=''){}
  • extract($_POST) es una gran vulnerabilidad: cualquiera puede establecer variables en su código desde el exterior.
  • $password == $data['pwd'] sugiere que esté almacenando contraseñas de texto sin formato en su base de datos. Esa es una práctica terrible. Google para "contraseña salada".
  • También puede hacer $loginOK = $password == $data['pwd'];. ¿Te das cuenta por qué? ;-)
5

¡Estás almacenando tus contraseñas en texto plano! Ese es un gran problema de seguridad si alguna vez lo vi. Qué hacer al respecto: al menos use un hash salado (por usuario) de la contraseña, como se ve, p.here.

+0

(siéntase libre de editar una explicación mejor de hash y salazón, esta es una que encontré al buscar rápidamente SO) – Piskvor

Cuestiones relacionadas