Xác định giới thiệu trong PHP


102

Cách đáng tin cậy và an toàn nhất để xác định trang nào được gửi hoặc được gọi (qua AJAX), trang hiện tại. Tôi không muốn sử dụng $_SERVER['HTTP_REFERER'], vì (thiếu) độ tin cậy và tôi cần trang được gọi chỉ đến từ các yêu cầu bắt nguồn từ trang web của tôi.

Chỉnh sửa: Tôi đang tìm cách xác minh rằng một tập lệnh định dạng trước một chuỗi hành động đang được gọi từ một trang trên trang web của tôi.


5
Tại sao bạn nói $ _SERVER ['HTTP_REFERER'] không đáng tin cậy?
Milan Babuškov

9
Việc triển khai PHP là đáng tin cậy. Vấn đề là không bao giờ trình duyệt gửi thông báo này, và bạn thậm chí có thể sửa đổi nó nếu bạn muốn. Vì vậy, nó là không đáng tin cậy mà là chính xác từ phía khách hàng.
Biri

2
Một cách khả thi là đặt một khóa duy nhất (ví dụ: GUID) vào một trường trên trang của bạn và gửi lại trong yêu cầu tiếp theo.
PhiLho 03/10/08

Tìm ra địa chỉ IP của máy chủ và sử dụng $_SERVER[REMOTE_ADDR].

Câu trả lời:


93

REFERER được gửi bởi trình duyệt của khách hàng như một phần của giao thức HTTP, và do đó thực sự không đáng tin cậy. Nó có thể không ở đó, nó có thể bị giả mạo, bạn chỉ không thể tin tưởng nó nếu nó vì lý do bảo mật.

Nếu bạn muốn xác minh xem một yêu cầu đến từ trang web của mình thì bạn không thể, nhưng bạn có thể xác minh rằng người dùng đã truy cập vào trang web của bạn và / hoặc đã được xác thực hay chưa. Cookie được gửi theo yêu cầu AJAX nên bạn có thể dựa vào đó.


5
Nếu bạn muốn sử dụng phương pháp này, bạn vẫn nên kiểm tra giới thiệu cũng như để ngăn chặn CSRF en.wikipedia.org/wiki/Cross-site_request_forgery
JD Isaacks

17
Lý tưởng nhất là bạn nên sử dụng một mã thông báo duy nhất cho mỗi phiên mỗi người dùng (theo yêu cầu nếu bạn hoang tưởng) để ngăn chặn các cuộc tấn công CSRF. Kiểm tra liên kết giới thiệu chỉ là bảo mật bằng cách xáo trộn và không phải là một giải pháp thực sự.
Seldaek

3
@Seldaek không, kiểm tra trình giới thiệu không phải là 'bảo mật bằng cách xáo trộn'. Kẻ tấn công đang cố gắng thực hiện một cuộc tấn công CSRF không thể kiểm soát trình giới thiệu được gửi bởi trình duyệt của nạn nhân, vì vậy việc kiểm tra nó sẽ bảo vệ khỏi CSRF. Tuy nhiên, tôi sẽ đưa ra kết luận của bạn rằng bạn nên sử dụng mã thông báo CSRF thay thế, vì phương pháp kiểm tra giới thiệu có những nhược điểm bao gồm khiến bạn dễ bị tổn thương nếu bạn có chuyển hướng mở trên trang web của mình và vi phạm đối với tác nhân người dùng tước bỏ giới thiệu.
Mark Amery

Tất cả đều phụ thuộc vào những gì bạn đang cố gắng chống lại tất nhiên, nhưng việc sử dụng tiêu đề http dành riêng cho máy khách nhìn chung không phải là một mô hình bảo mật mạnh mẽ.
Seldaek

23

Điều tôi thấy tốt nhất là mã thông báo CSRF và lưu nó trong phiên cho các liên kết mà bạn cần xác minh liên kết giới thiệu.

Vì vậy, nếu bạn đang tạo một cuộc gọi lại FB thì nó sẽ trông giống như sau:

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

Sau đó, index.php sẽ giống như sau:

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

//Continue with the rest of code

Tôi biết về các trang web an toàn thực hiện điều này tương đương với tất cả các trang an toàn của họ.


1
Dưới đây là một liên kết để biết thêm về CSRF mã thông báo: en.wikipedia.org/wiki/Cross-site_request_forgery
We0

7
Bạn có chắc rằng nó được $_GET['token'] == $_SESSION['token']và không $_GET['token'] !== $_SESSION['token']?
Timo Huovinen

17

Sử dụng $ _SERVER ['HTTP_REFERER']

Địa chỉ của trang (nếu có) đã giới thiệu tác nhân người dùng đến trang hiện tại. Điều này được đặt bởi tác nhân người dùng. Không phải tất cả các tác nhân người dùng sẽ đặt điều này và một số cung cấp khả năng sửa đổi HTTP_REFERER dưới dạng một tính năng. Trong ngắn hạn, nó không thể thực sự đáng tin cậy.

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

0

Không có cách nào đáng tin cậy để kiểm tra điều này. Nó thực sự dưới bàn tay của khách hàng để cho bạn biết nó đến từ đâu. Bạn có thể tưởng tượng sử dụng thông tin về cookie hoặc phiên chỉ đặt trên một số trang trên trang web của mình, nhưng làm như vậy sẽ phá vỡ trải nghiệm người dùng với dấu trang.


0

Chúng tôi chỉ còn lại một lựa chọn duy nhất sau khi đọc tất cả các vấn đề về liên kết giới thiệu giả mạo: tức là Trang chúng tôi muốn theo dõi dưới dạng liên kết giới thiệu nên được giữ trong phiên và khi ajax được gọi sau đó kiểm tra phiên nếu nó có giá trị trang liên kết giới thiệu và thực hiện hành động khôn ngoan khác không hoạt động.

Mặt khác, khi anh ta yêu cầu bất kỳ trang nào khác, sau đó làm cho giá trị phiên của liên kết giới thiệu thành null.

Hãy nhớ rằng biến phiên chỉ được đặt trên yêu cầu trang mong muốn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.