2008-10-03 6 views
94

Quelle est la manière la plus fiable et la plus sûre de déterminer quelle page a été envoyée ou appelée (via AJAX), la page actuelle. Je ne veux pas utiliser le $_SERVER['HTTP_REFERER'], en raison de la (manque de) fiabilité, et j'ai besoin que la page soit appelée pour provenir uniquement de demandes provenant de mon site. Editer: Je cherche à vérifier qu'un script qui préforme une série d'actions est appelé à partir d'une page sur mon site Web.Détermination de Referer en PHP

+5

Pourquoi dites-vous $ _SERVER ['HTTP_REFERER'] n'est pas fiable? –

+8

L'implémentation PHP est fiable. Le problème est que jamais le navigateur ne l'envoie, et vous pouvez même le modifier si vous le souhaitez. Donc, ce n'est pas fiable, c'est correct du côté du client. – Biri

+2

Un moyen possible est de mettre une clé unique (par exemple un GUID) dans un champ de votre page, et de le renvoyer dans la prochaine requête. – PhiLho

Répondre

87

Le REFERER est envoyé par le navigateur du client dans le cadre du protocole HTTP, et n'est donc pas fiable. Il pourrait ne pas être là, il pourrait être falsifié, vous ne pouvez pas lui faire confiance si c'est pour des raisons de sécurité.

Si vous souhaitez vérifier si une demande provient de votre site, eh bien vous ne pouvez pas, mais vous pouvez vérifier que l'utilisateur a été sur votre site et/ou est authentifié. Les cookies sont envoyés dans les requêtes AJAX afin que vous puissiez compter sur cela.

+5

Si vous souhaitez utiliser cette méthode, vous devez toujours vérifier le référent afin d'éviter CSRF http://en.wikipedia.org/wiki/Cross-site_request_forgery –

+16

Idéalement, vous devez utiliser un jeton unique par session par utilisateur (par demande si vous êtes paranoïaque) pour prévenir les attaques CSRF. Vérifier le référent est juste de la sécurité par obfuscation et pas tout à fait une vraie solution. – Seldaek

+2

@Seldaek non, vérifier le référant n'est pas «sécurité par obfuscation». Un attaquant essayant d'effectuer une attaque CSRF ne peut pas contrôler le referer envoyé par le navigateur de la victime, donc le vérifier * protège * contre CSRF. Cependant, je maintiens votre conclusion que vous devriez utiliser un jeton CSRF à la place, puisque l'approche de vérification de référant a [désavantages] (https://www.owasp.org/index.php/Cross-Site_Request_Forgery_ (CSRF) _Prevention_Cheat_Sheet #Checking_The_Referer_Header), y compris en vous laissant vulnérable si vous avez une redirection ouverte sur votre site et en cassant pour les agents utilisateurs qui dépouillent le referer. –

0

Il n'existe aucun moyen fiable de vérifier cela. C'est vraiment sous la main du client de vous dire d'où ça vient. Vous pouvez imaginer utiliser des cookies ou des informations sur les sessions mises seulement sur certaines pages de votre site Web, mais en faisant cela, votre expérience utilisateur avec les signets serait rompue.

0

Nous avons seulement seule option qui reste après avoir lu tous les faux problèmes referrer: -à-dire La page que nous désirons suivre comme referrer devrait être maintenu en session, et comme ajax appelé alors la vérification en session si elle a une valeur de page referrer et faire l'action autrement sage aucune action. D'autre part, comme il demande une page différente, alors la valeur de la session de référant est nulle. N'oubliez pas que la variable de session est définie uniquement sur la demande de page désirée.

12

En utilisant $_SERVER [ 'HTTP_REFERER']

L'adresse de la page (le cas échéant) qui a renvoyé l'agent utilisateur à la page en cours . Ceci est défini par l'agent utilisateur. Tous les agents utilisateurs ne définiront pas cela, et certains permettent de modifier HTTP_REFERER en tant que fonctionnalité . En bref, on ne peut pas vraiment faire confiance.

if (!empty($_SERVER['HTTP_REFERER'])) { 
    header("Location: " . $_SERVER['HTTP_REFERER']); 
} else { 
    header("Location: index.php"); 
} 
exit; 
+3

Je ne vois pas comment cela est pertinent du tout; en fait, il ignore si complètement la question qu'il se comporte comme du spam. – felwithe

21

Ce que j'ai trouvé meilleur est un jeton CSRF et l'enregistrer dans la session pour des liens où vous avez besoin de vérifier le referrer.

Donc, si vous générez un rappel de FB, alors il ressemblerait à quelque chose comme ceci:

$token = uniqid(mt_rand(), TRUE); 
$_SESSION['token'] = $token; 
$url = "http://example.com/index.php?token={$token}"; 

Alors le index.php ressemblera à ceci:

if(empty($_GET['token']) || $_GET['token'] !== $_SESSION['token']) 
{ 
    show_404(); 
} 

//Continue with the rest of code 

Je connais des sites sécurisés qui font l'équivalent de cela pour toutes leurs pages sécurisées.

+1

Voici un lien pour en savoir plus sur les jetons CSRF: http://en.wikipedia.org/wiki/Cross-site_request_forgery – We0

+7

Etes-vous sûr que c'est $ _GET ['token'] == $ _SESSION ['token'] 'et pas' $ _GET ['jeton']! == $ _SESSION ['token'] '? –

Questions connexes