2010-04-05 15 views
5

Tengo un script PHP que verifica el HTTP Referer.

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

Sin embargo, esto parece inherintly insegura ... porque ¿qué ocurre si el usuario va a 'http://example.com/' o 'http://www.ExaMple.com' (ambos de los cuales no coinciden con la prueba de igualdad).

Pregunta: ¿Cuál es la mejor prueba de igualdad para asegurarse de que HTTP Referer proviene del 'example.com'?

+0

¿Lo está utilizando para la defensa? ¿Cómo puede ayudar? –

+0

Es solo una primera línea de defensa (especialmente dado que sé que el árbitro puede ser engañado). No protege nada seguro, pero al mismo tiempo, no quiero que la gente abuse de mi servicio web llamándolo directamente. Está más destinado a mantener a las personas medio honestas. – Hank

+0

Un usuario puede controlar el http_referer utilizando datos de sabotaje. Sin embargo, el referidor no puede ser "falsificado" para ser utilizado en un ataque CSRF. – rook

Respuesta

1

Respuesta obligatoria: HTTP_REFERER puede ser falso, por lo que no hay forma de estar 100% seguro de que alguien provenga de un sitio web específico.

Sin embargo, si desea confiar en él, puede usar una expresión regular para buscar "example.com" en HTTP_REFERER. stristr() también funcionaría, y probablemente sería recomendable ya que sería más rápido que una expresión regular. También se distingue entre mayúsculas y minúsculas por lo que se correspondería con "ExaMple.com", así como 'example.com" función.

+0

Lo sé, gracias. Pero esa no es la pregunta. – Hank

+0

(Todavía es una primera línea de defensa decente, pero gracias por mencionarlo independientemente) – Hank

+1

pero no * stristr * también coincidiría en "notmyExample.com", ¿qué sería indeseable? – Hank

1

Espero que no te comprobar que nada significativo.

puede utilizar parse_url() para obtener parte de host y para comprobar si HTTP_REFERER en realidad contienen una URL. www
también puede simplemente sUBSTR. de nombre de host.
caso carácter no es importante, ya que siempre es minúscula

o utilizar una expresión regular.

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

¿Qué tal ...

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

No estoy seguro de que esto funcione todo el tiempo porque eso supone 1) una barra inclinada, 2) que "www". está presente en lugar de que el usuario vaya directamente a http://example.com – Hank

+0

Las URL siempre deben estar canonicalizadas, es decir, redirigir el dominio secundario al principal (cuando se usan varios dominios). http://en.wikipedia.org/wiki/Canonicalization – jholster

+0

@Hank - Verifique mi respuesta nuevamente ... –

3

parse_url() combinado con un poco de malabarismo cadena debe hacer lo que quiera. Prueba esto:

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

Tenga en cuenta que parse_url() puede fallar en URLs mal formados, por lo que es posible que desee añadir un poco de comprobación de errores para ser seguro. HTTP_REFERER podría llenarse fácilmente con basura.

0

Usando una expresión regular, esto se convertiría en

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