Pregunta

¿Qué tan peligroso es este código php? ¿Qué se puede hacer al respecto?

$name = $_POST["user"];
$pwd = $_POST["pwd"];
$query = "SELECT name,pwd FROM users WHERE name = '$name' AND pwd = '$pwd'";
¿Fue útil?

Solución

Posibles problemas:

  1. Inyección SQL
  2. Inyección XSS (si este código fuera una consulta de inserción, sería un problema definido)
  3. Contraseña de texto sin formato

Su declaración SQL puede ser problemática. Es una mala práctica dejarse abierto para la inyección de SQL.

La inyección SQL es mala . Confía en mí.

Si desea mostrar el usuario $ en una página HTML, es posible que no desee incluir la posibilidad de que la gente " piratear " su diseño escribiendo comandos como

<H1>HI MOM</H1>

o un montón de javascript .

Además, nunca almacene su contraseña en texto plano (¡buena captura cagcowboy!). Da demasiado poder a las personas que administran (o piratean) su base de datos. Nunca debe NECESITAR la contraseña de alguien.

Pruebe tácticas como estas:

// mostly pulled from http://snippets.dzone.com/posts/show/2738
function MakeSafe($unsafestring) 
{
    $unsafestring= htmlentities($unsafestring, ENT_QUOTES);

    if (get_magic_quotes_gpc()) 
    { 
        $unsafestring= stripslashes($unsafestring); 
    }

    $unsafestring= mysql_real_escape_string(trim($unsafestring));
    $unsafestring= strip_tags($unsafestring);
    $unsafestring= str_replace("\r\n", "", $unsafestring);

    return $unsafestring;
} 

// Call a function to make sure the variables you are 
// pulling in are not able to inject sql into your 
// sql statement causing massive doom and destruction.

$name = MakeSafe( $_POST["user"] );
$pwd = MakeSafe( $_POST["pwd"] );

// As suggested by cagcowboy: 
// You should NEVER store passwords decrypted.
// Ever.  
// sha1 creates a hash of your password
// pack helps to shrink your hash
// base64_encode turns it into base64
$pwd = base64_encode(pack("H*",sha1($pwd)))

Otros consejos

Es peligroso: xkcd bobby tables

Dejando a un lado la inyección SQL, parece que sus contraseñas podrían estar almacenadas en texto plano, lo que no es bueno.

Ese código es muy seguro si nunca pasa $ query a una base de datos SQL.

Si uno publicara 0';drop table users;-- para un nombre

tu comando terminaría siendo

select name, pwd form users where name='0'; 
drop table users; --'and pwd = '[VALUE OF PWD]'

Entonces, primero obtendría sus datos, luego eliminaría su tabla de usuarios y no haría nada con el resto, ya que es un comentario.

Ciertos comandos mysql en php realizarán múltiples consultas cuando se pasa sql, la mejor manera de evitar esto es consultas parametrizadas.

Utilizo PDO para todos mis accesos a bases de datos y lo recomiendo encarecidamente. No tengo ningún enlace en la parte superior de mi cabeza, pero recuerdo que los tutoriales que utilicé superaron a Google.

No solo es propenso a las inyecciones de SQL, también fallará en los casos en que ni siquiera se pretende una inyección:

Por ejemplo, un usuario quiere el nombre " Guillaume Fran & # 231; ois Antoine, Marquis de L & # 8217; Hospital " ;. Como el nombre de usuario contiene una cita y no se le escapa, su consulta fallará, ¡aunque el usuario nunca quiso romper el sistema!

Utilice PDO o hágalo de esta manera:

$query = sprintf(
                   "SELECT 1 FROM users WHERE name = '%s' AND password = '%s'",
                   mysql_real_escape_string($_POST['name']),
                   mysql_real_escape_string(md5($_POST['password']))
                 );

Créalo o no, esto es seguro ... si magic_quotes_gpc está activado. Que nunca estará en PHP6, por lo que arreglarlo antes de eso es una buena idea.

  1. $_POST['user'] = "' or 1=1; --"; Cualquier persona tiene acceso instantáneo a su aplicación

  2. $_POST['user'] = "'; DROP TABLE user; --"; Adiós a tu lista de usuarios (¿pagados?)

  3. Si luego repite $ name en su salida, eso puede resultar en un ataque de inyección XSS

: O no lo hagas nunca, Esto puede causar un ataque de SQLInjection. Si, por ejemplo, el usuario ingresa de alguna manera:   'usuarios de la tabla desplegable - como entrada en $ nombre de usuario; este código se concatenará con su código original y descartará su tabla. Los hackers pueden hacer más y pueden hackear su sitio web.

Esto suele ser muy peligroso. Podría mitigarse con los permisos de la base de datos en algunos casos.

No valida la entrada ($ name y $ pwd). Un usuario podría enviar SQL en uno o ambos de estos campos. El SQL podría eliminar o modificar otros datos en su base de datos.

Muy, muy peligroso. Una buena idea para las contraseñas es convertir la contraseña en un hash MD5 y almacenarla como la 'contraseña' del usuario.
1) protege a los usuarios de que les roben sus contraseñas 2) si un usuario escribe una cadena maliciosa, podría borrar su entrada / tabla / base de datos

También debe hacer alguna expresión de expresión regular de coincidencia en el nombre para asegurarse de que solo use A-Za-z0-9 y tal vez algunos caracteres acentuados (sin caracteres especiales, * 's, < , > en particular).

Cuando los datos del usuario se invocan en una consulta SQL, siempre desinfecte los datos con mysql_real_escape_string .

Además, debe almacenar solo un hash salado de la contraseña en lugar de la contraseña en sí. Puede usar la siguiente función para generar y verificar un hash salado con un valor de sal aleatorio:

function saltedHash($data, $hash=null)
{
    if (is_null($hash)) {
        $salt = substr(md5(uniqid(rand())), 0, 8);
    } else {
        $salt = substr($hash, 0, 8);
    }
    $h = $salt.md5($salt.$data);
    if (!is_null($hash)) {
        return $h === $hash;
    }
    return $h;
}

Todos juntos:

$query = 'SELECT pwd FROM users WHERE name = "'.mysql_real_escape_string($_POST['user']).'"';
$res = mysql_query($query);
if (mysql_num_rows($res)) {
   $row = mysql_fetch_assoc($res);
   if (saltedHash($_POST["pwd"], $row['pwd'])) {
       // authentic
   } else {
       // incorrect password
   }
} else {
   // incorrect username
}

No es seguro, es posible que desee buscar algo como PDO. PHP PDO

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