Bestimmen des Referers in PHP

102

Was ist der zuverlässigste und sicherste Weg, um festzustellen, welche Seite die aktuelle Seite gesendet oder aufgerufen hat (über AJAX). Ich möchte das $_SERVER['HTTP_REFERER']wegen der (mangelnden) Zuverlässigkeit nicht verwenden, und ich brauche, dass die aufgerufene Seite nur von Anfragen stammt, die von meiner Site stammen.

Bearbeiten: Ich möchte überprüfen, ob ein Skript, das eine Reihe von Aktionen ausführt, von einer Seite auf meiner Website aufgerufen wird.

UnkwnTech
quelle
5
Warum ist $ _SERVER ['HTTP_REFERER'] nicht zuverlässig?
Milan Babuškov
9
Die PHP-Implementierung ist zuverlässig. Das Problem ist, dass dies niemals von einem Browser gesendet wird und Sie es sogar ändern können, wenn Sie möchten. Es ist also nicht zuverlässig, ob dies vom Kunden aus richtig ist.
Biri
2
Eine Möglichkeit besteht darin, einen eindeutigen Schlüssel (z. B. eine GUID) in ein Feld Ihrer Seite einzufügen und ihn bei der nächsten Anforderung zurückzusenden.
PhiLho
Finden Sie die IP-Adresse des Servers heraus und verwenden Sie sie $_SERVER[REMOTE_ADDR].

Antworten:

93

Der REFERER wird vom Browser des Clients als Teil des HTTP-Protokolls gesendet und ist daher in der Tat unzuverlässig. Es könnte nicht da sein, es könnte gefälscht sein, man kann es einfach nicht vertrauen, wenn es aus Sicherheitsgründen ist.

Wenn Sie überprüfen möchten, ob eine Anfrage von Ihrer Site kommt, können Sie dies nicht. Sie können jedoch überprüfen, ob der Benutzer auf Ihrer Site war und / oder authentifiziert ist. Cookies werden in AJAX-Anfragen gesendet, sodass Sie sich darauf verlassen können.

Seldaek
quelle
5
Wenn Sie diese Methode verwenden möchten, sollten Sie noch die Referrer überprüfen und CSRF zu verhindern en.wikipedia.org/wiki/Cross-site_request_forgery
JD Isaacks
17
Idealerweise sollten Sie ein eindeutiges Token pro Sitzung und Benutzer verwenden (pro Anfrage, wenn Sie paranoid sind), um CSRF-Angriffe zu verhindern. Das Überprüfen des Überweisers ist nur Sicherheit durch Verschleierung und keine echte Lösung.
Seldaek
3
@Seldaek nein, die Überprüfung des Referers ist keine "Sicherheit durch Verschleierung". Ein Angreifer versucht , einen CSRF - Angriff durchführen kann durch Browser des Opfers überprüft nicht den Referer steuern gesendet, so dass es funktioniert Schutz vor CSRF. Ich werde jedoch zu Ihrer Schlussfolgerung stehen, dass Sie stattdessen ein CSRF-Token verwenden sollten, da der Referer-Checking-Ansatz Nachteile hat , z. B. Sie verwundbar zu machen, wenn Sie eine offene Weiterleitung auf Ihrer Site haben und nach Benutzeragenten suchen, die den Referer entfernen.
Mark Amery
@MarkAmery alles hängt natürlich davon ab, gegen was Sie sich verteidigen möchten, aber die Verwendung von clientspezifischen http-Headern ist insgesamt kein sehr starkes Sicherheitsmodell.
Seldaek
23

Was ich am besten gefunden habe, ist ein CSRF-Token, das in der Sitzung für Links gespeichert wird, über die Sie den Referrer überprüfen müssen.

Wenn Sie also einen FB-Rückruf generieren, sieht dieser ungefähr so ​​aus:

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

Dann sieht die index.php folgendermaßen aus:

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

//Continue with the rest of code

Ich kenne sichere Websites, die für alle ihre sicheren Seiten das Gleiche tun.

We0
quelle
1
Hier ist ein Link für weitere
Informationen
7
Bist du sicher, dass es so ist $_GET['token'] == $_SESSION['token']und nicht $_GET['token'] !== $_SESSION['token']?
Timo Huovinen
17

Verwenden von $ _SERVER ['HTTP_REFERER']

Die Adresse der Seite (falls vorhanden), die den Benutzeragenten auf die aktuelle Seite verwiesen hat. Dies wird vom Benutzeragenten festgelegt. Nicht alle Benutzeragenten legen dies fest, und einige bieten die Möglichkeit, HTTP_REFERER als Funktion zu ändern. Kurz gesagt, es kann nicht wirklich vertraut werden.

if (!empty($_SERVER['HTTP_REFERER'])) {
    header("Location: " . $_SERVER['HTTP_REFERER']);
} else {
    header("Location: index.php");
}
exit;
Lawrence Cherone
quelle
0

Es gibt keine zuverlässige Möglichkeit, dies zu überprüfen. Es liegt wirklich in der Hand des Kunden, Ihnen zu sagen, woher es kommt. Sie können sich vorstellen, Cookie- oder Sitzungsinformationen zu verwenden, die nur auf einigen Seiten Ihrer Website gespeichert sind. Andernfalls würde die Benutzererfahrung mit Lesezeichen beeinträchtigt.

Gizmo
quelle
0

Wir haben nur noch eine Option, nachdem wir alle gefälschten Referrer-Probleme gelesen haben: dh Die Seite, die wir als Referrer verfolgen möchten, sollte in der Sitzung bleiben, und als Ajax aufgerufen, dann in der Sitzung einchecken, ob sie den Wert der Referrer-Seite hat, und die Aktion auf andere Weise ausführen Aktion.

Wenn er andererseits eine andere Seite anfordert, setzen Sie den Wert der Referrer-Sitzung auf null.

Denken Sie daran, dass die Sitzungsvariable nur auf Wunschanforderungsseite festgelegt wird.

justnajm
quelle