¿Hay alguna inyección de SQL para este ejemplo de inicio de sesión de PHP?

9

Quiero escribir un formulario de inicio de sesión y recibí un ejemplo de la web. Quiero saber, si hay alguna inyección de SQL para este código? Si existe, ¿cómo podría ser la entrada del formulario web del exploit?

Este es mi formulario:

<form method="post" action="">
    <dt class="title"><label for="username">name:</label></dt>
    <dt><input type="text" name="username" id="username"  size="50"></dt>
    <dt class="title"><label for="password">pass:</label></dt>
    <dt><input type="password" name="password" id="password" size="50"></dt>
    <input type="hidden" name="post" value="1" />
    <input type="submit" name="submit" value="submit" class="button">
</form>

y este es mi cheque:

if (($post[username]) AND ($post[password])) 
    {
        $query = 'SELECT * FROM 'config' WHERE 'config_admin_username'="'.$post[username].'" AND 'config_admin_password'=MD5("'.$post[password].'") LIMIT 1';
        $sql_user_check = $db->fetch($query);
        if (!$sql_user_check) { 
            $error .= "Wrong Entry.<br />";
        } else {
            $_SESSION[admin] = 1;
            header("Location:index.php");
            exit;
        }
    }

Estoy usando phpmyadmin 3.2.0.1 en wamp 2.0i

    
pregunta sorroshsaket 22.04.2013 - 00:44
fuente

3 respuestas

19

Has venido al lugar correcto. ¡Bienvenido a seguridad de TI !

  

¿hay alguna inyección de sql para este código?

  

si hay lo que es esa entrada?

username: [any username from your website]" /*
password: sux0r")*/ OR ("1"="1

Ejecutará esta consulta:

SELECT * FROM 'config' 
WHERE 'config_admin_username'="[any username from your website]" /* 
      AND 'config_admin_password'=MD5("sux0r")*/ OR ("1"="1") LIMIT 1'

Si eliminamos las partes comentadas que el motor SQL no analiza, esto da como resultado:

SELECT * FROM 'config' 
WHERE 'config_admin_username'="[any username from your website]" OR ("1"="1") LIMIT 1'

La consulta SQL se analizará hasta la parte comentada (usé el par /* y */ start-comment / end-comment en mi ejemplo y asumiendo que estás usando MySQL , pero puede ser diferente según el RDBMS utilizado), deshabilitando de forma efectiva la verificación de su contraseña. Incluso si los comentarios en SQL no son compatibles o están deshabilitados, las opciones para explotar su inicio de sesión son realmente ilimitadas. Ni siquiera voy a entrar en su elección de MD5 como algoritmo de hash de contraseña, ya que tiene que considerar muchas otras cosas primero. Claramente, no es el algoritmo hash recomendado para el hashing de contraseñas.

Ha hecho bien en haber venido a este sitio web y se está haciendo preguntas sobre la seguridad de su código. ¡Felicidades, ya eres un mejor programador de PHP que la mayoría de los que nunca llegaste a ser! Ahora, depende de usted qué aprenderá de las preguntas y respuestas ya existentes aquí. Algunas etiquetas a considerar son , , , , ...

    
respondido por el TildalWave 22.04.2013 - 01:05
fuente
9

TildalWave tiene una gran respuesta, pero hay una gran mediación para la inyección de SQL que faltaba en la respuesta. Declaraciones preparadas. Como dijo Tildal, toda la declaración con la entrada del usuario se analiza sin distinción analizable entre variables y partes constantes de la declaración. La solución es enviar la parte constante de la declaración con los marcadores de posición variables y luego las variables. DOP es lo que uso para mi interacción SQL. Aquí está la función que uso ...

function _SQL_QUERY($_base_request, $_request_arguments)
{
                $_DB_USERNAME = "bob"; $_DB_PASSWORD="secret"; $_DB_LOCATION="localhost"; $_DB_NAME="MYWICKEDDATABASE"; $_DB_SERVER_TYPE="mysql";
                if(!isset($_DATABASE_CONNECTION))
                {
                        $_DATABASE_CONNECTION = new PDO("$_DB_SERVER_TYPE:dbname=$_DB_NAME;host=$_DB_LOCATION;charset=utf8", $_DB_USERNAME, $_DB_PASSWORD);
                        $_DATABASE_CONNECTION->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
                }
                $__STMT = $_DATABASE_CONNECTION->prepare($_base_request);
                if($__STMT->execute($_request_arguments))
                {
                        return $__STMT;
                }
                else
                {
/*
        //Helpful ONLY when debugging!!!
                        echo 'ERROR</ br>';
                        echo $_base_request;
                        echo '</ br>';
                        print_r($__STMT->errorInfo());
                        print_r($_request_arguments);
                        die('</ br>');
*/
                        return false;
                }
}

para usarlo solo necesitas ejecutar esto

_SQL_QUERY("Select * FROM names WHERE name=:var1 AND age=:var2", array('var1'=>'jim','var2'=>50));

Se pueden realizar muchas mejoras (principalmente funcionales) a esto, pero es una gran mejora de las funciones SQL tradicionales. Por cierto, es importante saber que si una fila tiene un intento fallido de inyección en sus datos, una copia de seguridad y una restauración pueden hacer que tenga éxito, según el método utilizado. Felicitaciones por hacer una auditoría de seguridad de su código, si solo más personas aprendieron a programar con esa motivación hacia la seguridad.

    
respondido por el David 22.04.2013 - 09:10
fuente
-2

Si lo es. No estás validando nada. Tienes que usar

  • mysql_real_escape_string para evitar la inyección de SQL
  • htmlentities / htmlspecialchars para evitar ataques XSS

Eche un vistazo a este tutorial ya que ayuda en el aprendizaje para evitar la inyección de SQL.

    
respondido por el Damian 26.04.2013 - 09:32
fuente

Lea otras preguntas en las etiquetas