Menentukan Referer di PHP

102

Apa cara yang paling andal dan aman untuk menentukan halaman mana yang dikirim, atau disebut (melalui AJAX), halaman saat ini. Saya tidak ingin menggunakan $_SERVER['HTTP_REFERER'], karena (kurangnya) keandalan, dan saya ingin laman dipanggil hanya berasal dari permintaan yang berasal dari situs saya.

Sunting: Saya ingin memverifikasi bahwa skrip yang membentuk serangkaian tindakan dipanggil dari laman di situs web saya.

UnkwnTech
sumber
5
Mengapa Anda mengatakan $ _SERVER ['HTTP_REFERER'] tidak dapat diandalkan?
Milan Babuškov
9
Implementasi PHP dapat diandalkan. Masalahnya adalah bahwa tidak pernah browser yang mengirimkan ini, dan Anda bahkan dapat memodifikasinya jika Anda mau. Jadi tidak reliabel yang benar dari sisi klien.
Biri
2
Cara yang mungkin adalah dengan meletakkan kunci unik (mis. GUID) di satu bidang halaman Anda, dan mengirimkannya kembali di permintaan berikutnya.
PhiLho
Cari tahu alamat IP server dan gunakan $_SERVER[REMOTE_ADDR].

Jawaban:

93

REFERER dikirim oleh browser klien sebagai bagian dari protokol HTTP, dan karena itu memang tidak dapat diandalkan. Mungkin tidak ada, mungkin dipalsukan, Anda tidak bisa mempercayainya jika itu untuk alasan keamanan.

Jika Anda ingin memverifikasi apakah permintaan datang dari situs Anda, Anda tidak bisa, tetapi Anda dapat memverifikasi bahwa pengguna telah ke situs Anda dan / atau diautentikasi. Cookie dikirim dalam permintaan AJAX sehingga Anda dapat mengandalkannya.

Seldaek
sumber
5
Jika Anda ingin menggunakan metode ini, Anda harus tetap memeriksa pengarah juga untuk mencegah CSRF en.wikipedia.org/wiki/Cross-site_request_forgery
JD Isaacks
17
Idealnya Anda harus menggunakan token unik per sesi per pengguna (per permintaan jika Anda paranoid) untuk mencegah serangan CSRF. Memeriksa perujuk hanyalah keamanan dengan kebingungan dan bukan solusi nyata.
Seldaek
3
@Seldaek tidak, memeriksa perujuk bukanlah 'keamanan dengan kebingungan'. Penyerang mencoba untuk melakukan serangan CSRF tidak bisa mengontrol referer dikirim oleh browser korban, sehingga memeriksa itu tidak melindungi terhadap CSRF. Namun, saya akan berpegang pada kesimpulan Anda bahwa Anda harus menggunakan token CSRF sebagai gantinya, karena pendekatan pemeriksaan perujuk memiliki kerugian termasuk membuat Anda rentan jika Anda memiliki pengalihan terbuka di situs Anda dan melanggar agen pengguna yang menghapus perujuk.
Mark Amery
@MarkAmery tentu saja semuanya tergantung pada apa yang Anda coba pertahankan, tetapi menggunakan header http khusus klien secara keseluruhan bukan model keamanan yang sangat kuat.
Seldaek
23

Yang paling saya temukan adalah token CSRF dan menyimpannya di sesi untuk tautan di mana Anda perlu memverifikasi perujuk.

Jadi jika Anda membuat panggilan balik FB maka akan terlihat seperti ini:

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

Kemudian index.php akan terlihat seperti ini:

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

//Continue with the rest of code

Saya tahu situs aman yang melakukan hal yang sama untuk semua halaman aman mereka.

We0
sumber
1
Berikut ini tautan untuk lebih lanjut tentang token CSRF: en.wikipedia.org/wiki/Cross-site_request_forgery
We0
7
Apakah Anda yakin itu benar $_GET['token'] == $_SESSION['token']dan tidak $_GET['token'] !== $_SESSION['token']?
Timo Huovinen
17

Menggunakan $ _SERVER ['HTTP_REFERER']

Alamat halaman (jika ada) yang mengarahkan agen pengguna ke halaman saat ini. Ini diatur oleh agen pengguna. Tidak semua agen pengguna akan menyetel ini, dan beberapa menyediakan kemampuan untuk mengubah HTTP_REFERER sebagai fitur. Singkatnya, itu tidak bisa dipercaya.

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

Tidak ada cara yang dapat diandalkan untuk memeriksa ini. Ini benar-benar di bawah tangan klien untuk memberi tahu Anda dari mana asalnya. Anda dapat membayangkan untuk menggunakan cookie atau informasi sesi yang hanya ditempatkan di beberapa halaman situs web Anda, tetapi melakukannya akan merusak pengalaman pengguna dengan bookmark.

alat
sumber
0

Kami hanya memiliki satu pilihan tersisa setelah membaca semua masalah pengarah palsu: yaitu halaman yang ingin kita lacak sebagai pengarah harus disimpan dalam sesi, dan sebagai panggilan ajax kemudian memeriksa sesi jika memiliki nilai halaman pengarah dan melakukan tindakan lainnya tidak bijaksana tindakan.

Sementara di sisi lain saat dia meminta halaman yang berbeda maka buat nilai sesi perujuk menjadi null.

Ingat bahwa variabel sesi disetel hanya pada permintaan halaman keinginan.

justnajm
sumber