2010-04-05 56 views
5

Tôi có một tập lệnh PHP để kiểm tra HTTP Referer.

if ($_SERVER['HTTP_REFERER'] == 'http://www.example.com/') {...} 

Tuy nhiên, điều này dường như inherintly không an toàn ... vì những gì xảy ra nếu người dùng đi vào 'http://example.com/' hoặc 'http://www.ExaMple.com' (cả hai đều không phù hợp với kiểm tra bình đẳng).

Câu hỏi: kiểm tra bình đẳng tốt hơn để đảm bảo rằng HTTP Referer đến từ 'example.com' là gì?

+0

Bạn đang sử dụng nó cho quốc phòng? Làm thế nào nó có thể giúp đỡ? –

+0

Nó chỉ là một dòng đầu tiên của quốc phòng (đặc biệt là cho tôi biết người giới thiệu có thể được giả mạo). Nó không bảo vệ bất cứ điều gì an toàn nhưng đồng thời, tôi không muốn mọi người lạm dụng dịch vụ web của tôi bằng cách gọi trực tiếp. Nó có nghĩa là để giữ cho người bán trung thực. – Hank

+0

Người dùng có thể kiểm soát http_referer bằng cách sử dụng dữ liệu giả mạo. Tuy nhiên, người giới thiệu không thể "giả mạo" được sử dụng trong một cuộc tấn công CSRF. – rook

Trả lời

1

Trả lời bắt buộc: HTTP_REFERER có thể bị giả mạo vì vậy không có cách nào đảm bảo 100% mọi người đến từ một trang web cụ thể.

Tuy nhiên, nếu bạn muốn dựa vào nó, bạn có thể sử dụng regex để tìm "example.com" trong HTTP_REFERER. stristr() cũng sẽ hoạt động, và có thể sẽ được khuyến khích vì nó sẽ nhanh hơn sau đó là một regex. Nó cũng là trường hợp nhạy cảm vì vậy nó sẽ phù hợp với "ExaMple.com" cũng như 'example.com".

+0

Tôi biết, cảm ơn. Nhưng đó không phải là câu hỏi. – Hank

+0

(Nó vẫn là một dòng phòng thủ đầu tiên, nhưng cảm ơn vì đã đề cập đến nó bất kể) – Hank

+1

nhưng sẽ không * stristr * cũng phù hợp với "notmyExample.com" mà sẽ là không mong muốn? – Hank

1

Hy vọng bạn không kiểm tra xem nó cho bất cứ điều gì đáng kể.

bạn có thể sử dụng parse_url() chức năng để có được hostname phần và để kiểm tra xem HTTP_REFERER chứa thực sự là một url www.
bạn cũng có thể chỉ substr. từ hostname.
trường hợp nhân vật không phải là quan trọng vì nó luôn thường

hoặc sử dụng một regexp.

0
if (strtolower($_SERVER['HTTP_REFERER']) == 'http://www.example.com/') {...} 

Làm thế nào về ...

$parts = explode('/',$_SERVER['HTTP_REFERER']); 
if (in_array('example.com',$parts) || in_array('www.example.com',$parts)) {...} 
+1

Không chắc chắn điều này sẽ làm việc tất cả các thời gian vì đó giả định 1) một dấu gạch chéo, 2) rằng "www." có mặt thay vì người dùng truy cập trực tiếp vào http://example.com – Hank

+0

URL phải luôn được chuẩn hóa, tức là tên miền phụ chuyển hướng đến tên miền phụ (khi nhiều tên miền được sử dụng). http://en.wikipedia.org/wiki/Canonicalization – jholster

+0

@Hank - Kiểm tra lại câu trả lời của tôi ... –

3

parse_url() kết hợp với một chút chuỗi tung hứng nên làm những gì bạn muốn. Hãy thử điều này:

$url = parse_url($_SERVER['HTTP_REFERER']); 
//take the last two 'dot segments' of the host 
$hostOnly = implode('.',array_slice(explode('.',$url['host']),-2)); 
if (strtolower($hostOnly) == 'example.com') { 
    //stuff 
} 

Lưu ý rằng parse_url() có thể bị lỗi trên URL được tạo thành sai, vì vậy bạn có thể muốn thêm một số lỗi kiểm tra để an toàn. HTTP_REFERER có thể dễ dàng được lấp đầy với rác.

0

Sử dụng một regex, điều này sẽ trở thành

if(preg_match("%(http://)?(www\.)?example\.com(/)?%i",$_SERVER['HTTP_REFERER'])) { ... } 
Các vấn đề liên quan