Domanda

Quanto è pericoloso questo codice php? Cosa si può fare al riguardo?

$name = $_POST["user"];
$pwd = $_POST["pwd"];
$query = "SELECT name,pwd FROM users WHERE name = '$name' AND pwd = '$pwd'";
È stato utile?

Soluzione

Possibili problemi:

  1. Iniezione SQL
  2. Iniezione XSS (se questo codice fosse una query di inserimento, sarebbe un problema definito)
  3. Password in testo normale

L'istruzione SQL può essere problematica. È una buona pratica lasciarti aperto per l'iniezione di SQL.

SQL Injection non è valido . Fidati di me.

Se vuoi mostrare $ user su una pagina HTML, allora potresti non voler includere la possibilità per le persone di " hack " il tuo layout digitando comandi come

<H1>HI MOM</H1>

o un gruppo di javascript .

Inoltre, non memorizzare mai la tua password in testo semplice (buona cattura cagcowboy!). Dà troppo potere alle persone che gestiscono (o hackerano) il tuo database. Non dovresti mai BISOGNO di conoscere la password di qualcuno.

Prova tattiche come queste:

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

Altri suggerimenti

È così pericoloso: tavoli bobby xkcd

SQL Injection a parte, sembra che le tue password possano essere memorizzate in testo semplice, il che non è eccezionale.

Questo codice è molto sicuro se non passi mai $ query a un database SQL.

Se uno dovesse pubblicare 0';drop table users;-- per un nome

il tuo comando finirebbe per essere

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

Quindi prima otterrebbe i tuoi dati, quindi ucciderebbe la tabella degli utenti e non fare nulla con il resto poiché si tratta di un commento.

Alcuni comandi mysql in php eseguiranno più query quando passano sql, il modo migliore per evitarlo sono le query parametrizzate.

Uso PDO per tutto il mio accesso al DB e lo consiglio vivamente. Non ho alcun link nella parte superiore della mia testa, ma ricordo i tutorial che ho usato in cima a Google.

Non è solo soggetto a iniezioni di SQL, ma fallirà anche nei casi in cui un'iniezione non è nemmeno prevista:

Ad esempio un utente vuole il nome " Guillaume Fran & # 231; ois Antoine, Marquis de L & # 8217; Hospital " ;. Dato che il nome utente contiene un preventivo e non lo stai sfuggendo, la tua query fallirà, sebbene l'utente non abbia mai voluto rompere il sistema!

Usa PDO o fallo in questo modo:

$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']))
                 );

Che ci crediate o no, questo è sicuro ... se magic_quotes_gpc è attivato. Che non sarà mai in PHP6, quindi risolverlo prima di allora è una buona idea.

  1. $_POST['user'] = "' or 1=1; --"; Chiunque ha accesso immediato alla tua app

  2. $_POST['user'] = "'; DROP TABLE user; --"; Bacia addio alla tua lista utenti (a pagamento?)

  3. Se in seguito si riecheggia $ name nell'output, ciò può provocare un attacco di iniezione XSS

: O non farlo mai e poi mai Ciò può causare un attacco SQLInjection. Se ad esempio l'input dell'utente in qualche modo:   "Utenti della tabella a discesa - come input in $ nome utente; questo codice si concatenerà al tuo codice originale e lascerà cadere la tabella. Gli hacker possono fare di più e hackerare il tuo sito Web.

Questo è in genere molto pericoloso. In alcuni casi potrebbe essere mitigato dalle autorizzazioni del database.

Non convalidi l'input ($ name e $ pwd). Un utente potrebbe inviare SQL in uno o entrambi questi campi. L'SQL potrebbe eliminare o modificare altri dati nel database.

Molto molto pericoloso. Una buona idea per le password è convertire la password in un hash MD5 e memorizzarla come "password" dell'utente.
1) protegge gli utenti dal furto delle loro password 2) se un utente scrive una stringa dannosa potrebbe cancellare la tua voce / tabella / database

Inoltre dovresti fare alcune espressioni regex di corrispondenza di base sul nome per assicurarti che usi solo A-Za-z0-9 e forse alcuni caratteri accentati (nessun carattere speciale, * 's, <' s , > in particolare).

Quando i dati utente sono coinvolti in una query SQL, sanatizzare sempre i dati con mysql_real_escape_string .

Inoltre, dovresti archiviare solo un hash salato della password anziché la password stessa. Puoi utilizzare la seguente funzione per generare e controllare un hash salato con un valore salt casuale:

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

Tutti insieme:

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

Non è sicuro, potresti voler esaminare qualcosa come il DOP. PHP PDO

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top