Esiste un'iniezione SQL per questo esempio di accesso PHP?

9

Voglio scrivere un modulo di accesso e ho ricevuto un esempio dal web. Voglio sapere, se c'è qualche iniezione SQL per questo codice? Se esiste, quale potrebbe essere la voce del modulo Web di exploit?

Questa è la mia forma:

<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>

e questo è il mio assegno:

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;
        }
    }

Sto usando phpmyadmin 3.2.0.1 su wamp 2.0i

    
posta sorroshsaket 22.04.2013 - 00:44
fonte

3 risposte

19

Sei arrivato nel posto giusto. Benvenuto in sicurezza IT !

is there any sql injection for this code?

if there is what is that Entry?

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

Eseguirà questa query:

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

Se rimuoviamo le parti commentate che il motore SQL non analizzerà, ciò si traduce in:

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

La query SQL verrà analizzata fino alla parte commentata (ho usato la coppia /* e */ start-comment / end-comment nel mio esempio e supponendo che tu stia usando MySQL , ma può variare a seconda dell'RDBMS utilizzato), disabilitando completamente il controllo della password. Anche se i commenti in-SQL non sono supportati o disabilitati, le opzioni per sfruttare i tuoi dati di accesso sono davvero illimitate. Non entrerò nemmeno nella tua scelta di MD5 come algoritmo di hashing della password, dato che hai un sacco di altre cose da considerare prima. Tuttavia, non è chiaramente l'algoritmo hash raccomandato per l'hashing della password.

Hai fatto bene ad accedere a questo sito Web e ti stai facendo delle domande sulla sicurezza del tuo codice. Complimenti, sei già un programmatore PHP migliore di molti che non sono mai stati così lontani! Ora, tocca a te quello che imparerai dalle domande e risposte già esistenti qui. Alcuni tag da considerare sono , , , , ...

    
risposta data 22.04.2013 - 01:05
fonte
9

TildalWave ha un'ottima risposta, ma c'è una grande mediazione all'iniezione SQL che mancava nella risposta. Dichiarazioni preparate. Come ha affermato Tildal, l'intera istruzione con input dell'utente viene analizzata senza alcuna distinzione analizzabile tra le variabili e le parti costanti dell'istruzione. La soluzione sta inviando la parte costante dell'istruzione con segnaposti variabili quindi le variabili. DOP è ciò che utilizzo per la mia interazione SQL. Ecco la funzione che 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;
                }
}

per utilizzarlo dovresti solo eseguire questo

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

Ci sono molti miglioramenti da apportare (principalmente funzionali) a questo, ma è un enorme miglioramento rispetto alle tradizionali funzioni SQL. BTW è importante sapere che se una riga ha un tentativo fallito di un'iniezione nei suoi dati, un backup e un ripristino potrebbero effettivamente riuscire in base al metodo utilizzato. Complimenti per aver fatto un controllo di sicurezza del tuo codice, se solo più persone avessero imparato a programmare con quella motivazione verso la sicurezza.

    
risposta data 22.04.2013 - 09:10
fonte
-2

Sì, lo è. Non stai convalidando nulla. Devi usare

  • mysql_real_escape_string per impedire l'iniezione SQL
  • htmlentities / htmlspecialchars per prevenire attacchi XSS

Dai un'occhiata a questo tutorial in quanto aiuta l'apprendimento per prevenire l'iniezione SQL.

    
risposta data 26.04.2013 - 09:32
fonte

Leggi altre domande sui tag