Dovrei mysql_real_escape_string tutti i cookie che ricevo dall'utente per evitare l'iniezione di mysql in php?

StackOverflow https://stackoverflow.com/questions/90517

  •  01-07-2019
  •  | 
  •  

Domanda

Quando un utente accede al mio sito, il mio script verifica la presenza di 2 cookie che memorizzano l'ID utente + parte della password, per accedervi automaticamente.

È possibile modificare il contenuto dei cookie tramite un editor di cookie, quindi immagino sia possibile aggiungere contenuto dannoso a un cookie scritto?

Dovrei aggiungere mysql_real_escape_string (o qualcos'altro) a tutte le mie chiamate cookie o esiste una sorta di procedura integrata che non consente che ciò accada?

È stato utile?

Soluzione

Cosa tu Veramente Ciò che devi fare è non inviare questi valori dei cookie che sono in primo luogo hackerabili.Invece, perché non eseguire l'hashing del nome utente, della password e di un sale (segreto) e impostarlo come valore del cookie?cioè.:

define('COOKIE_SALT', 'secretblahblahlkdsfklj');
$cookie_value = sha1($username.$password.COOKIE_SALT);

Quindi sai che il valore del cookie sarà sempre una stringa esadecimale di 40 caratteri e puoi confrontare il valore che l'utente restituisce con qualunque cosa sia presente nel database per decidere se sono validi o meno:

if ($user_cookie_value == sha1($username_from_db.$password_drom_db.COOKIE_SALT)) {
  # valid
} else {
  #not valid
}

mysql_real_escape_string fa un ulteriore successo al database, a proposito (molte persone non si rendono conto che richiede una connessione DB e interroga MySQL).

Il modo migliore per fare quello che vuoi se non puoi cambiare la tua app e insisti nell'usare valori di cookie modificabili è usare istruzioni preparate con parametri associati.

Altri suggerimenti

Lo scopo di mysql_real_escape_string non è proteggere dagli attacchi injection, ma garantire che i dati siano archiviati accuratamente nel database.Pertanto, dovrebbe essere richiamato su QUALSIASI stringa che entra nel database, indipendentemente dalla sua origine.

Dovresti, tuttavia, Anche utilizzare query parametrizzate (tramite mysqli o PDO) per proteggersi dall'iniezione SQL.Altrimenti rischi di finire come la scuola della piccola Bobby Tables.

Utilizzo solo mysql_real_escape_string prima di inserire variabili in un'istruzione SQL.Ti confonderai solo se alcune delle tue variabili lo sono Già sei scappato, e poi scappi di nuovo da loro.È un classico bug che vedi nelle webapp dei blog dei principianti:

Quando qualcuno scrive un apostrofo continua ad aggiungere barre rovinando le pagine del blog.

Il valore di una variabile non è pericoloso di per sé:è solo quando lo metti in una corda o qualcosa di simile che inizi a vagare in acque pericolose.

Naturalmente, però, non fidarti mai di nulla che provenga dal lato client.

Le istruzioni preparate e l'associazione dei parametri sono sempre una buona strada da percorrere.

PEAR::MDB2 supporta istruzioni preparate, ad esempio:

$db = MDB2::factory( $dsn );

$types = array( 'integer', 'text' );
$sth = $db->prepare( "INSERT INTO table (ID,Text) (?,?)", $types );
if( PEAR::isError( $sth ) ) die( $sth->getMessage() );

$data = array( 5, 'some text' );
$result = $sth->execute( $data );
$sth->free();
if( PEAR::isError( $result ) ) die( $result->getMessage() );

Ciò consentirà solo ai dati corretti e alla quantità preimpostata di variabili di entrare nel database.

Ovviamente dovresti convalidare i dati prima di arrivare a questo punto, ma preparare le dichiarazioni è la convalida finale che dovrebbe essere eseguita.

Dovresti mysql_real_escape_string nulla potrebbe essere potenzialmente dannoso.Non fidarti mai di qualsiasi tipo di input che possa essere modificato dall'utente.

Sono d'accordo con te.È possibile modificare i cookie e inviare dati dannosi.

Credo che sia buona pratica filtrare i valori che ottieni dai cookie prima di utilizzarli.Come regola generale filtro qualsiasi altro input che potrebbe essere manomesso.

Yegor, puoi memorizzare l'hash quando un account utente viene creato/aggiornato, quindi ogni volta che viene avviato un accesso, esegui l'hashing dei dati pubblicati sul server e li confronti con ciò che è stato memorizzato nel database per quel nome utente.

(In cima alla mia testa in php sciolto - trattalo come pseudo codice):

$usernameFromPostDbsafe = LimitToAlphaNumUnderscore($usernameFromPost);
$result = Query("SELECT hash FROM userTable WHERE username='$usernameFromPostDbsafe' LIMIT 1;");
$hashFromDb = $result['hash'];
if( (sha1($usernameFromPost.$passwordFromPost.SALT)) == $hashFromDb ){
    //Auth Success
}else{
   //Auth Failure
}

Dopo un'autenticazione riuscita, è possibile archiviare l'hash in $_SESSION o in una tabella di database di nome utente/hash autenticati memorizzati nella cache.Quindi invia nuovamente l'hash al browser (ad esempio in un cookie) in modo che i successivi caricamenti della pagina inviino l'hash al server per confrontarlo con l'hash conservato nell'archivio della sessione prescelta.

mysql_real_escape_string è così superato...Al giorno d'oggi dovresti davvero utilizzare l'associazione dei parametri.

Elaborerò menzionando ciò a cui mi riferivo dichiarazioni preparate e fornisci un collegamento a un articolo che dimostra che a volte mysl_real_escape_string non è sufficiente: http://www.webappsec.org/projects/articles/091007.txt

Consiglierei di utilizzare htmlentities($input, ENT_QUOTES) invece di mysql_real_escape_string poiché ciò impedirà anche qualsiasi output accidentale del codice HTML effettivo.Ovviamente potresti usare mysql_real_escape_string e htmlentities, ma perché dovresti?

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