Domanda

I stava parlando con uno dei miei programmatori in precedenza e mi ha mostrato un pezzo di codice che stava pensando:

foreach($_REQUEST as $var=>$val) {
    $$var = addslashes($val);
}

Voleva essere in grado di utilizzare $varName invece di dover scrivere $_REQUEST['varName']

Gli ho consigliato di utilizzare il mysql_real_escape_string invece di addSlashes e di non mettere le variabili $_REQUEST nello stack locale, perché questo dà un hacker allegare vettoriale. A me sembra che lo stesso problema che la vecchia direttiva REGISTER_GLOBALS aveva.

Ha detto che non c'era la stessa rischi per la sicurezza, perché le variabili sono stati tutti creati sullo stack locale. Quindi ero incerto e ho controllato la pagina variabili variabile PHP all'indirizzo: http: //www.php.net/manual/en/language.variables.variable.php ma ha visto alcun riferimento a Super Globals e sicurezza altri poi la finestra di avvertimento.

Gli hacker possono facilmente approfittare di questo costrutto?

È stato utile?

Soluzione

Questo è come tornare indietro di 6 anni di miglioramenti alla sicurezza PHP ... Fondamentalmente, register_globals e magic_quotes messi insieme! Quei due sono contrassegnati deprecato nelle ultime versioni di PHP, e saranno rimossi da future versioni, per ottime ragioni.

Immaginate il seguente codice:

if ($is_admin) {
    do_administrative_task();
}

Ora qualcuno fa la seguente richiesta:

http://www.example.com/script.php?is_admin=1

E proprio così, sei amministratore!

Allo stesso modo, addslashes() in realtà non fornisce alcuna protezione contro gli attacchi di SQL injection, perché non capisce i set di caratteri moderni. E 'ridicolmente facile mestiere qualcosa che bypass addslashes() e PWN il database.

Altri suggerimenti

Non ho codificato php in anni, ma non c'è una funzione che fa questo? Forse chiamato estratto ?

Ci sono un paio di avvertimenti circa utilizzando tale funzione con i dati utente immessi .. questi avvertimenti si applicherebbe a snippet di codice pure.

Il "stack locale" non ha nulla a che fare con esso. Esso consente ancora a chiunque di creare una nuova variabile in qualche parte del codice che il programmatore non può aver anctipated.

Se davvero vuole prendere i parametri di richiesta di $_REQUEST e fare le variabili di tutti, allora dovrebbe trasferire solo quelli che il codice sta per cercare e non di più.

E addslashes() fosso. Che non è solo il luogo sbagliato per sfuggire dati in arrivo, ma la funzione sbagliata, troppo.

Sì. Se l'URL della richiesta contiene ...&GLOBALS[var]=1 allora sovrascriverà la variabile globale secondo.

Si dovrebbe almeno prendere in considerazione seguente costrutto per la sicurezza:

 extract($_REQUEST, EXTR_PREFIX_ALL, "var_");  // or EXTR_SKIP

Questo vi darà le variabili localizzate almeno un prefisso e impedire la sovrascrittura delle variabili globali. Per buona misura anche l'uso array_map("addslashes", $_REQUEST) o una funzione di fuga più appropriato. Ma in realtà, questo è solo magic_quotes con un altro nome. (Offtopic:. Cercare di lasciar andare via mysql_query e utilizzare DOP e prepared statement, che è più semplice e più sicuro)

Proprio così! Come il programmatore in questione ci sono in realtà tre questioni separate qui.

  1. Questo $_REQUEST non è più insicuro di $_GET o $_POST visto che da PHP impostazione predefinita $_COOKIES ha la precedenza su $_GET e $_POST.
  2. Impostazione valore di un superglobale è più sicuro di una variabile locale in una funzione o una variabile locale metodo di un oggetto.
  3. utente finale variabile creata in funzione sono globalmente accessibile.

La partenza di Let in alto.

  1. $_POST e $_GET non sono più sicuro di $_REQUEST. Tutte le informazioni ricevute da un form è sporca. Periodo. Indipendentemente. Se posso inviare nei cookie falsi ho il know how per le variabili POST falsi. L'argomento è discutibile.
  2. Quindi prendiamo una variabile locale che creiamo con $var. La portata di questa variabile è soltanto all'interno della funzione / metodo. È l'impostazione del contenuto di una superglobale al valore dei dati forniti dall'utente più sicura di una variabile locale che viene allo scrub quando lo stack funzione / metodo viene pulita? Mi chiedo ...
  3. Consente di prendere un frammento

function some_function() {
   foreach($_POST as $var=>$val) {
        $$var = $val; 
  }
}

Ora, se $_POST contiene una variabile denominata _POST questo codice imposterà un $_POST variabile locale contenente il valore. Tuttavia, superglobals ignorerà questa e qualsiasi riferimento $_POST riconosceranno l'superglobale, non la variabile locale e come tale la $_POST locale è unrefereceable. Data questa funzionalità di PHP, senza utilizzare la parola chiave globale che di norma è impossibile ignorare completamente il superglobale

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