Określanie Referer w PHP

102

Jaki jest najbardziej niezawodny i bezpieczny sposób określenia, która strona wysłała lub wywołała (przez AJAX) bieżącą stronę. Nie chcę używać $_SERVER['HTTP_REFERER'], ze względu na (brak) niezawodności i chcę, aby wywoływana strona pochodziła tylko z żądań pochodzących z mojej witryny.

Edycja: Chcę sprawdzić, czy skrypt, który wykonuje serię działań, jest wywoływany ze strony w mojej witrynie.

UnkwnTech
źródło
5
Dlaczego mówisz, że $ _SERVER ['HTTP_REFERER'] nie jest wiarygodne?
Milan Babuškov
9
Implementacja PHP jest niezawodna. Problem polega na tym, że przeglądarka nigdy tego nie wysyła, a jeśli chcesz, możesz to nawet zmodyfikować. Nie jest więc wiarygodne, czy jest to poprawne ze strony klienta.
Biri
2
Możliwym sposobem jest umieszczenie unikalnego klucza (np. GUID) w jednym polu strony i odesłanie go w następnym żądaniu.
PhiLho
Znajdź adres IP serwera i użyj $_SERVER[REMOTE_ADDR].

Odpowiedzi:

93

REFERER jest wysyłany przez przeglądarkę klienta jako część protokołu HTTP i dlatego jest rzeczywiście zawodny. Może go tam nie być, może być sfałszowane, po prostu nie możesz mu ufać, jeśli jest to ze względów bezpieczeństwa.

Jeśli chcesz sprawdzić, czy żądanie pochodzi z Twojej witryny, nie możesz, ale możesz sprawdzić, czy użytkownik był w Twojej witrynie i / lub jest uwierzytelniony. Pliki cookie są wysyłane w żądaniach AJAX, więc możesz na tym polegać.

Seldaek
źródło
5
Jeśli chcesz użyć tej metody, powinieneś również sprawdzić stronę odsyłającą, aby zapobiec CSRF en.wikipedia.org/wiki/Cross-site_request_forgery
JD Isaacks
17
W idealnym przypadku powinieneś użyć unikalnego tokena na sesję na użytkownika (na żądanie, jeśli masz paranoję), aby zapobiec atakom CSRF. Sprawdzanie strony odsyłającej to tylko zabezpieczenie przez zaciemnienie i niezupełnie realne rozwiązanie.
Seldaek
3
@Seldaek nie, sprawdzanie referer nie jest „zabezpieczeniem przez zaciemnienie”. Osoba atakująca próbuje przeprowadzić atak CSRF nie może kontrolować odsyłający wysłana przez przeglądarkę ofiary, więc sprawdzenie to nie chroni przed CSRF. Podtrzymuję jednak Twój wniosek, że zamiast tego powinieneś użyć tokena CSRF, ponieważ podejście do sprawdzania referencji ma wady, w tym naraża Cię na niebezpieczeństwo, jeśli masz otwarte przekierowanie w swojej witrynie i łamie się dla klientów użytkownika, które usuwają odsyłacz.
Mark Amery,
@MarkAmery, wszystko zależy od tego, przed czym próbujesz się bronić, ale używanie specyficznych dla klienta nagłówków http nie jest ogólnie bardzo silnym modelem bezpieczeństwa.
Seldaek
23

To, co znalazłem najlepiej, to token CSRF i zapisz go w sesji dla linków, w których musisz zweryfikować stronę odsyłającą.

Więc jeśli generujesz wywołanie zwrotne FB, wyglądałoby to mniej więcej tak:

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

Wtedy plik index.php będzie wyglądał następująco:

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

//Continue with the rest of code

Wiem o bezpiecznych witrynach, które robią to samo dla wszystkich swoich bezpiecznych stron.

We0
źródło
1
Tutaj jest link, aby uzyskać więcej informacji na temat tokenów CSRF: en.wikipedia.org/wiki/Cross-site_request_forgery
We0
7
Czy na pewno tak jest, $_GET['token'] == $_SESSION['token']a nie $_GET['token'] !== $_SESSION['token']?
Timo Huovinen,
17

Korzystanie z $ _SERVER ['HTTP_REFERER']

Adres strony (jeśli istnieje), która odesłała klienta użytkownika do bieżącej strony. Jest to ustawiane przez klienta użytkownika. Nie wszystkie programy użytkownika to ustawiają, a niektóre zapewniają możliwość modyfikowania protokołu HTTP_REFERER jako funkcji. Krótko mówiąc, naprawdę nie można mu ufać.

if (!empty($_SERVER['HTTP_REFERER'])) {
    header("Location: " . $_SERVER['HTTP_REFERER']);
} else {
    header("Location: index.php");
}
exit;
Lawrence Cherone
źródło
0

Nie ma niezawodnego sposobu, aby to sprawdzić. Klient może naprawdę powiedzieć, skąd się to wzięło. Możesz sobie wyobrazić, że używasz plików cookie lub informacji o sesjach umieszczonych tylko na niektórych stronach Twojej witryny, ale w ten sposób zepsujesz doświadczenie użytkownika z zakładkami.

gadżet
źródło
0

Po przeczytaniu wszystkich problemów z fałszywymi adresami odsyłającymi pozostała tylko jedna opcja: tj. Strona, którą chcemy śledzić jako odsyłająca, powinna być utrzymywana w sesji, a jako wywołanie Ajaxa, a następnie sprawdzanie w sesji, czy ma wartość strony odsyłającej, i wykonanie czynności w inny sposób nie akcja.

Z drugiej strony, gdy zażąda innej strony, ustaw wartość sesji odsyłającej na zero.

Pamiętaj, że zmienna sesji jest ustawiana tylko na żądanie strony.

justnajm
źródło