2010-04-05 10 views
5

Ho uno script PHP che controlla l'HTTP Referer.

if ($_SERVER['HTTP_REFERER'] == 'http://www.example.com/') {...} 

Tuttavia, questo sembra inherintly pericoloso ... perché cosa succede se l'utente va a 'http://example.com/' o 'http://www.ExaMple.com' (entrambi i quali non corrispondono al test di uguaglianza).

Domanda: qual è un test di uguaglianza migliore per garantire che l'HTTP Referer provenga da 'example.com'?

+0

Si sta utilizzando per la difesa? Come può aiutare? –

+0

E 'solo una prima linea di difesa (soprattutto dato che so che il referente può essere falsificato). Non protegge nulla, ma allo stesso tempo, non voglio che le persone abusino del mio servizio web chiamandolo direttamente. È più destinato a mantenere le persone semi-oneste. – Hank

+0

Un utente può controllare il http_referer utilizzando i dati di manomissione. Tuttavia, il referente non può essere "forgiato" per essere usato in un attacco CSRF. – rook

risposta

1

Risposta obbligatoria: HTTP_REFERER può essere contraffatto quindi non c'è modo di essere sicuri al 100% che qualcuno provenga da un sito Web specifico.

Tuttavia, se si desidera fare affidamento su di esso, è possibile utilizzare un'espressione regolare per cercare "esempio.com" in HTTP_REFERER. stristr() funzionerebbe anche, e probabilmente sarebbe raccomandato poiché sarebbe più veloce di una regex. E 'anche maiuscole e minuscole in modo che sarebbe partita "ExaMple.com" e 'example.com" la funzione.

+0

Lo so, grazie. Ma non è questa la domanda. – Hank

+0

(È ancora una prima linea difensiva decente, ma grazie per averlo menzionato a prescindere) – Hank

+1

ma non * stristr * corrisponde anche a "notmyExample.com" che sarebbe indesiderabile? – Hank

1

Spero che non si controlla per qualcosa di significativo.

è possibile utilizzare parse_url() per ottenere parte hostname e per verificare se HTTP_REFERER contengono in realtà un URL. www
si può anche solo substr. da hostname.
caso personaggio non è importante in quanto è sempre in minuscolo

o usare un espressione regolare.

0
if (strtolower($_SERVER['HTTP_REFERER']) == 'http://www.example.com/') {...} 

ne dite ...

$parts = explode('/',$_SERVER['HTTP_REFERER']); 
if (in_array('example.com',$parts) || in_array('www.example.com',$parts)) {...} 
+1

Non è sicuro che funzionerà sempre perché ciò presuppone 1) una barra finale, 2) quella "www." è presente invece che l'utente che accede direttamente a http://example.com – Hank

+0

Gli URL dovrebbero sempre essere canonizzati, cioè reindirizzare il dominio secondario a quello primario (quando si utilizzano più domini). http://en.wikipedia.org/wiki/Canonicalization – jholster

+0

@Hank - Controlla di nuovo la mia risposta ... –

3

parse_url() combinato con un po 'di giocoleria stringa dovrebbe fare quello che vuoi. Prova questo:

$url = parse_url($_SERVER['HTTP_REFERER']); 
//take the last two 'dot segments' of the host 
$hostOnly = implode('.',array_slice(explode('.',$url['host']),-2)); 
if (strtolower($hostOnly) == 'example.com') { 
    //stuff 
} 

noti che parse_url() può fallire su URL mal formate, così si potrebbe desiderare di aggiungere un po 'di controllo degli errori di essere al sicuro. HTTP_REFERER potrebbe facilmente essere riempito con junk.

0

Usando un'espressione regolare, questo sarebbe diventato

if(preg_match("%(http://)?(www\.)?example\.com(/)?%i",$_SERVER['HTTP_REFERER'])) { ... } 
Problemi correlati