2011-02-01 30 views
25

Tôi đang tạo một hệ thống với CakePHP cần được bảo mật một cách rõ ràng, bởi vì chúng tôi đang xử lý tiền, tài khoản của khách hàng, v.v. Cho đến giờ mọi thứ đều hoạt động tốt, cho đến khi tôi phải tích hợp với nền tảng thanh toán Tôi cần phải chuyển hướng đến trang web của họ và họ chuyển hướng trở lại của tôi.Session.referer_check của PHP bảo vệ tôi từ đâu?

Điều này hoạt động tốt trong máy tính của tôi (debug = 2), nhưng trong sản xuất, khi khách hàng được chuyển hướng trở lại, anh nhận được nhắc đăng nhập thay vì quay trở lại trong "khu vực đăng nhập" của mình. Sau nhiều lần tìm hiểu, tôi thấy điều này là do CakePHP đặt session.referer_check, điều này làm mất hiệu lực phiên nếu HTTP_REFERER đến từ một máy chủ khác so với tôi.

Bây giờ, thông thường, tôi sẽ vô hiệu hóa tính năng này mà không suy nghĩ lần hai, nhưng trong hệ thống này, tôi quan tâm nhiều đến vấn đề bảo mật hơn bình thường.

Câu hỏi của tôi chính xác là session.referer_check có nghĩa vụ bảo vệ tôi từ đâu?
Loại tấn công/khai thác/điều xấu nào có thể được thực hiện cho trang web của tôi nếu tôi tắt tính năng này?

Tôi đoán rằng có một số lý do tại sao điều này tồn tại, nhưng tôi không thể tưởng tượng nó sẽ bảo vệ tôi khỏi điều gì.

Bạn có thể cho tôi bất kỳ ý tưởng nào không?
Tắt tính năng này có an toàn không?

Cảm ơn bạn
Daniel

+0

Bạn có 100% đang kiểm tra liên kết giới thiệu chứ không phải mã thông báo được gửi cùng với biểu mẫu trong yêu cầu trước đó để bảo vệ chống lại CSRF không? – Pablo

+0

Chắc chắn 100%. CakePHP không kiểm tra liên kết giới thiệu, nó chỉ bật tính năng referer_check (một tính năng PHP kiểm tra chính liên kết giới thiệu: http://www.php.net/manual/en/session.configuration.php#ini.session.referer-check) - Ngoài ra, kết quả tôi thấy là đăng nhập mọi người. Những gì CakePHP làm khi nó không giống như mã thông báo CSRF nó nhận được (hoặc khi nó không nhận được một) là "blackholing" (trang trống, về cơ bản) –

+0

Tương tự: http://stackoverflow.com/questions/22079477/cakephp -session-is-lost-after-an-oauth-redirect – trante

Trả lời

22

Điều này nhằm bảo vệ giới hạn cho Session Fixation và CSRF/XSRF. Kiểm tra người giới thiệu là a valid method of stopping xsrf. Phương pháp dừng phiên cố định tốt hơn là Session.use_only_cookies, bởi vì tin tặc không thể đặt cookie trên trình duyệt nạn nhân cho miền mà anh ấy chưa kiểm soát.

Tuy nhiên, Session.referer_checkrất dễ bỏ qua. Chỉ tìm kiếm chuỗi con trong miền giới thiệu. Nếu chuỗi con bị thiếu tất cả cùng nhau, điều này xảy ra nếu url gốc là https: // thì id phiên sẽ không hợp lệ. Tuy nhiên, do chuỗi con của nó và không phải là chuỗi đầy đủ, bạn có thể bỏ qua chuỗi này cho www.somedomain.com bằng cách tham chiếu từ www.somedomain.com.some_hacker.com. Vì vậy, trong ngắn hạn, tôi nghĩ rằng đây là hoàn toàn vô dụng.

+0

Cảm ơn bạn rất nhiều vì câu trả lời của bạn! Điều này xóa nó lên! –

3

Kiểm tra referer theo cách này có thể giúp bảo vệ chống lại Cross-site request forgery. Lý tưởng nhất là bạn muốn có một cách để kiểm tra tham chiếu phù hợp với tên miền của bạn hoặc tên miền của nền tảng thanh toán, nhưng vì nó là một kiểm tra chuỗi con đơn giản chứ không phải là kết hợp mẫu, tôi không nghĩ rằng điều này sẽ là khả thi.

Nếu bạn tắt chức năng này, bạn nên áp dụng các biện pháp khác để bảo vệ chống lại các cuộc tấn công như vậy.

+0

Kiểm tra giới thiệu có thể bị giả mạo. Các mã thông báo không mã hóa hoặc một lần là tiêu chuẩn để bảo vệ chống lại CSRF. – gravelpot

+0

Tôi giả định là nhiều. Bây giờ, trong trang web của tôi, bạn không thể thay đổi bất kỳ thứ gì ** bằng cách sử dụng GET, chỉ POST, trang web sẽ không nhớ bạn sau khi bạn đóng trình duyệt và CakePHP đã tạo ra "mã thông báo ma thuật" để tránh các biểu mẫu XSRF . Với tất cả những điều đó trong tâm trí, tôi có thể vô hiệu hóa một cách an toàn điều này? –

+0

@gravelpot: Tiêu đề có thể được giả mạo bởi kẻ tấn công, nhưng đó không phải là những gì CSRF nói đến, đó là về việc trình duyệt của người dùng tự thực hiện yêu cầu từ trang web khác (độc hại) đến trang web (tốt) của bạn. Trong trường hợp đó, bạn không thể giả mạo một liên kết giới thiệu. (Và tôi đang sử dụng mã thông báo và mọi thứ trên trang web của tôi nằm sau bức tường đăng nhập không "nhớ bạn") –

4

Gấu nhớ rằng về cơ bản tất cả các referer_check đang làm là một cái gì đó như:

$pattern = "/^http:\/\/www\.myurl\.com(\/.*)*$/"; 

if(!empty($_SERVER['HTTP_REFERER']) && !preg_match($pattern, $_SERVER['HTTP_REFERER'])) { 
    session_destroy(); 
} 

Đó là gây phiền nhiễu mà PHPs xây dựng trong referer_check sẽ không chấp nhận một loạt các URL, nhưng bạn luôn có thể làm cho một riêng bạn điều đó.

Vì vậy, cho CakePHP, bạn có thể làm một cái gì đó như sau:

// ADD THIS TO /app/config/config.php 
$config['CustomSecurity'] = array(
    'accept_referers' => array(
     'http://www.my_site.com', 
     'https://www.other_allowed_referer.com', 
    ) 
); 

// ADD THIS TO /app/app_controller.php 

private function referer_check(){ 
    if(!empty($_SERVER['HTTP_REFERER'])) { 
     $accept_referers = Configure::read('CustomSecurity.accept_referers'); 
     $referer_accepted = false; 
     foreach($accept_referers as $referer) { 
     $pattern = '/^'.preg_replace('/(\.|\/)/','\\\$1',$referer).'(\/.*)*$/'; 
     if(preg_match($pattern, $_SERVER['HTTP_REFERER'])) 
      $referer_accepted = true; 
     } 
     if(!$referer_accepted) { 
     $this->Session->destroy(); 
     exit; 
     } 
    }   
} 

VÀ TRONG BẠN app_controller::before_filter CHỨC NĂNG, CALL:

$this->referer_check(); 

... hoặc một cái gì đó như thế nào ... xin lỗi về định dạng mã, văn bản đã là tài khoản :)

Các vấn đề liên quan