È $ _SERVER [] una fonte sicura di dati in PHP?

29

Posso contare al 100% su $_SERVER[] per essere una fonte sicura di dati che non ho bisogno di disinfettare come faccio io $_GET[] e $_POST[] ?

    
posta user2079272 09.03.2013 - 06:11
fonte

4 risposte

43

Questo è preso da una delle mie domande su Stack Overflow: Quali variabili $ _SERVER sono sicure?

Controllato dal server

Queste variabili sono impostate dall'ambiente server e dipendono interamente dalla configurazione del server.

  • 'GATEWAY_INTERFACE'
  • 'SERVER_ADDR'
  • 'SERVER_SOFTWARE'
  • 'DOCUMENT_ROOT'
  • 'SERVER_ADMIN'
  • 'SERVER_SIGNATURE'

In parte controllato dal server

Queste variabili dipendono dalla specifica richiesta inviata dal client, ma possono prendere solo un numero limitato di valori validi, poiché tutti i valori non validi dovrebbero essere rifiutati dal server Web e non causare l'inizio del richiamo dello script. Quindi possono essere considerati affidabili .

  • 'HTTPS'
  • 'REQUEST_TIME'
  • 'REMOTE_ADDR' *
  • 'REMOTE_HOST' *
  • 'REMOTE_PORT' *
  • 'SERVER_PROTOCOL'
  • 'HTTP_HOST'
  • 'SERVER_NAME'
  • 'SCRIPT_FILENAME'
  • 'SERVER_PORT'
  • 'SCRIPT_NAME'

* I valori di REMOTE_ sono garantiti come indirizzo valido del client, come verificato da un handshake TCP / IP. Questo è l'indirizzo a cui verrà inviata qualsiasi risposta. REMOTE_HOST fa affidamento su ricerche DNS inverse e potrebbe quindi essere falsificato dagli attacchi DNS contro il tuo server (nel qual caso hai comunque problemi più grandi). Questo valore può essere un proxy, che è una semplice realtà del protocollo TCP / IP e nulla di ciò che puoi fare.

† Se il tuo server web risponde a qualsiasi richiesta indipendentemente dall'intestazione HOST , questo dovrebbe essere considerato non sicuro. Vedi Quanto è sicuro $ _SERVER ["HTTP_HOST"]? .
Vedi anche link .

Valori controllati dall'utente interamente arbitrari

Questi valori non sono affatto controllati e non dipendono da alcuna configurazione del server, sono informazioni completamente arbitrarie inviate dal client.

  • 'argv' , 'argc' (applicabile solo alla chiamata CLI, di solito non riguarda i server Web)
  • 'REQUEST_METHOD'
  • 'QUERY_STRING'
  • 'HTTP_ACCEPT'
  • 'HTTP_ACCEPT_CHARSET'
  • 'HTTP_ACCEPT_ENCODING'
  • 'HTTP_ACCEPT_LANGUAGE'
  • 'HTTP_CONNECTION'
  • 'HTTP_REFERER'
  • 'HTTP_USER_AGENT'
  • 'AUTH_TYPE' §
  • 'PHP_AUTH_DIGEST' §
  • 'PHP_AUTH_USER' §
  • 'PHP_AUTH_PW' §
  • 'PATH_INFO'
  • 'ORIG_PATH_INFO'
  • 'REQUEST_URI' (può contenere dati contaminati)
  • 'PHP_SELF' (può contenere dati contaminati, ad esempio /index.php/evilstring)
  • 'PATH_TRANSLATED'
  • qualsiasi altro valore 'HTTP_'

‡ Può essere considerato affidabile a condizione che il server Web consenta solo determinati metodi di richiesta.

§ Può essere considerato affidabile se l'autenticazione è gestita interamente dal server web.

Anche il superglobale $_SERVER include diverse variabili d'ambiente. Se questi sono "sicuri" o non dipendono da come (e dove) sono definiti. Possono variare da completamente controllati da server a completamente controllati dall'utente.

    
risposta data 10.03.2013 - 21:16
fonte
14

Can I 100% rely on $_SERVER[] to be a safe source of data that I do not need to sanitized like I do $_GET[] and $_POST[]?

La tua domanda indica immediatamente un errore. Tutte le fonti di input devono essere igienizzate. L'input non è solo considerato come canali che l'utente può controllare direttamente, ma tutte le fonti di dati al di fuori dell'applicazione.

Pensaci in questo modo, la tua applicazione ha 2 modi per ottenere i dati: informazioni codificate nell'applicazione e input. Anche se è generato da un altro programma sullo stesso sistema, è comunque inserito nel tuo programma.

L'idioma comune Filter-In, Escape-Out non si applica solo all'input dell'utente, ma a tutto ciò che entra e lascia la tua applicazione.

Quindi, se è in $_SERVER , DEVE essere filtrato / disinfettato. Non dovresti mai fare affidamento su qualcosa che non è hard-coded nella tua applicazione.

Perché è così importante? Immaginiamo di filtrare tutti gli input dell'utente, ma poi fidati dei dati che provengono dal tuo database. Se riesco a sfruttare un buco nel tuo filtraggio, posso inserire dati che poi diventano affidabili. Ciò può causare XSS o SQLi di secondo ordine. Ma se filtri tutto ciò che entra nella tua applicazione, quando entra, indipendentemente da dove proviene, allora sarai al sicuro!

Quindi no, non puoi mai contare al 100% su qualsiasi cosa in $_SERVER , $_GET , $_POST , $_COOKIE , $_REQUEST , $_ENV , $argc , $argv , dal tuo database , dal filesystem (a parte il codice controllato dalla versione), ecc ...

    
risposta data 12.03.2013 - 21:00
fonte
6

Non una domanda stupida!

Molte (ma non tutte) le variabili $ SERVER vengono passate dal browser degli utenti (o possono essere influenzate dall'utente), ad esempio QUERY_STRING, REQUEST_URI e tutte le variabili HTTP_ *.

Anche la variabile REMOTE_ADDR può essere falsificata usando socket raw (anche se solo con IP validi per quanto ne so).

Mi piacerebbe scapparli tutti per una buona politica.

link

    
risposta data 09.03.2013 - 07:19
fonte
3

Non esiste una "fonte sicura di dati". Devi sempre assicurarti che i dati siano nel formato corretto quando li trasmetti a qualcos'altro.

Se stai eseguendo l'output su SQL all'interno di una stringa delimitata da un apostropo ('), dovresti evitare gli apostrofi (o qualsiasi altra cosa che potrebbe scomporre la stringa). Se stai eseguendo l'output su una stringa delimitata da un apostrofo Javascript [2], dovresti evitare entrambi gli HTML e gli apostrofi. Tutto dipende da cosa stai trasmettendo. Una stringa perfettamente sicura può spezzare lo script di destinazione, anche se non in modo malevolo. (Spesso però, se può essere rotto, può anche essere sfruttato.)

[1] Esempio: $db->query("SELECT * FROM users WHERE name = '$username'");
[2] Esempio: <script>alert('Hi <?php echo $username;?>');</script>

Ho parlato di questa fuga sul mio blog, anche se il mio post riguarda specificamente XSS. Penso che lo stesso principio si applichi anche qui: Che cos'è XSS e come proteggere il tuo sito web .

A meno che tu non sappia che il PHP stesso applica già un formato specifico, e non puoi quasi mai esserne sicuro, puoi considerare tutto non sicuro. Gli indirizzi IP di solito vengono nel formato x.x.x.x, ma potrebbe anche essere x: x: x: x: x: x: x: x per IPv6. O anche 0: 0: 0: 0: 0: ffff: x.x.x.x per le destinazioni IPv4 nei pacchetti IPv6. Se non sei a conoscenza di ciò, potrebbero verificarsi alcuni bug molto interessanti.

Ora un indirizzo IP non conterrà mai un apostrofo, giusto ..? Bene, ci sono quelle persone che controllano l'intestazione $ _SERVER ["HTTP_X_FORWARDED_FOR"] prima di usare l'indirizzo remoto. Questo è grandioso, purché l'intestazione sia impostata correttamente (come indicato anche da @Ladadadada in un commento alla risposta di @ GBC), ma potrebbe anche essere una parodia. Quindi, quando usi i dati che altri hanno memorizzato nel database, potresti recuperare oggetti dannosi ... Quindi, alla fine, non fidarti mai dell'input. Meglio fissarlo troppo rispetto a dimenticarlo una volta.

    
risposta data 10.03.2013 - 01:18
fonte

Leggi altre domande sui tag