Một số hướng dẫn để duy trì bảo mật phiên có trách nhiệm với PHP là gì? Có thông tin trên tất cả các trang web và đã đến lúc tất cả hạ cánh ở một nơi!
Một số hướng dẫn để duy trì bảo mật phiên có trách nhiệm với PHP là gì? Có thông tin trên tất cả các trang web và đã đến lúc tất cả hạ cánh ở một nơi!
Câu trả lời:
Có một số điều cần làm để giữ an toàn cho phiên của bạn:
$_SERVER['HTTP_USER_AGENT']
. Điều này thêm một rào cản nhỏ để chiếm quyền điều khiển phiên. Bạn cũng có thể kiểm tra địa chỉ IP. Nhưng điều này gây ra vấn đề cho người dùng đã thay đổi địa chỉ IP do cân bằng tải trên nhiều kết nối internet, v.v. (đó là trường hợp trong môi trường của chúng tôi ở đây).Một hướng dẫn là gọi session_regenerate_id mỗi khi mức bảo mật của phiên thay đổi. Điều này giúp ngăn chặn chiếm quyền điều khiển phiên.
Hai (hoặc nhiều hơn) xu của tôi:
Có một cuốn sách nhỏ nhưng hay về chủ đề này: Essential PHP Security của Chris Shiflett .
Bảo mật PHP thiết yếu http://shiflett.org/images/essential-php-security-small.png
Trên trang chủ của cuốn sách, bạn sẽ tìm thấy một số ví dụ mã thú vị và các chương mẫu.
Bạn có thể sử dụng kỹ thuật được đề cập ở trên (IP & UserAgent), được mô tả ở đây: Cách tránh hành vi trộm cắp danh tính
Tôi nghĩ một trong những vấn đề chính (đang được giải quyết trong PHP 6) là register_globals. Ngay bây giờ một trong những phương pháp chuẩn được sử dụng để tránh register_globals
là sử dụng $_REQUEST
, $_GET
hoặc $_POST
mảng.
Cách "chính xác" để làm điều đó (kể từ 5.2, mặc dù đó là một lỗi nhỏ ở đó, nhưng ổn định kể từ 6, sắp ra mắt) là thông qua các bộ lọc .
Vì vậy, thay vì:
$username = $_POST["username"];
bạn sẽ làm:
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
hoặc thậm chí chỉ:
$username = filter_input(INPUT_POST, 'username');
Bài viết cố định phiên này có con trỏ rất tốt nơi cuộc tấn công có thể đến. Xem thêm trang sửa lỗi phiên tại Wikipedia .
Sử dụng địa chỉ IP không thực sự là ý tưởng tốt nhất theo kinh nghiệm của tôi. Ví dụ; văn phòng của tôi có hai địa chỉ IP được sử dụng tùy thuộc vào tải và chúng tôi liên tục gặp sự cố khi sử dụng địa chỉ IP.
Thay vào đó, tôi đã chọn lưu trữ các phiên trong cơ sở dữ liệu riêng cho các tên miền trên máy chủ của mình. Bằng cách này, không ai trong hệ thống tệp có quyền truy cập vào thông tin phiên đó. Điều này thực sự hữu ích với phpBB trước 3.0 (họ đã sửa lỗi này) nhưng tôi nghĩ đó vẫn là một ý tưởng hay.
Điều này khá tầm thường và rõ ràng, nhưng hãy chắc chắn với session_destroy sau mỗi lần sử dụng. Điều này có thể khó thực hiện nếu người dùng không đăng xuất rõ ràng, vì vậy có thể đặt hẹn giờ để thực hiện việc này.
Đây là một hướng dẫn tốt về setTimer () và clearTimer ().
Vấn đề chính với các phiên và bảo mật PHP (bên cạnh việc chiếm quyền điều khiển phiên) đi kèm với môi trường bạn đang ở. Theo mặc định, PHP lưu trữ dữ liệu phiên trong một tệp trong thư mục tạm thời của hệ điều hành. Không có bất kỳ suy nghĩ đặc biệt hoặc lập kế hoạch, đây là một thư mục có thể đọc được trên thế giới, vì vậy tất cả thông tin phiên của bạn được công khai cho bất kỳ ai có quyền truy cập vào máy chủ.
Đối với việc duy trì phiên trên nhiều máy chủ. Tại thời điểm đó, tốt hơn là chuyển PHP sang các phiên do người dùng xử lý trong đó nó gọi các hàm được cung cấp của bạn thành CRUD (tạo, đọc, cập nhật, xóa) dữ liệu phiên. Tại thời điểm đó, bạn có thể lưu trữ thông tin phiên trong cơ sở dữ liệu hoặc memcache như giải pháp để tất cả các máy chủ ứng dụng có quyền truy cập vào dữ liệu.
Lưu trữ các phiên của riêng bạn cũng có thể thuận lợi nếu bạn ở trên một máy chủ dùng chung vì nó sẽ cho phép bạn lưu trữ nó trong cơ sở dữ liệu mà bạn thường kiểm soát nhiều hơn sau đó là hệ thống tệp.
Tôi thiết lập các phiên của mình như thế này-
trên trang đăng nhập:
$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);
(cụm từ được xác định trên trang cấu hình)
sau đó trên tiêu đề xuyên suốt phần còn lại của trang web:
session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {
session_destroy();
header('Location: http://website login page/');
exit();
}
session.cookie_httponly = 1
change session name from default PHPSESSID
X-XSS-Protection 1
X-XSS-Protection
không thực sự hữu ích chút nào. Trong thực tế, thuật toán bảo vệ chính nó thực sự có thể bị khai thác, làm cho nó tồi tệ hơn trước.
Tôi sẽ kiểm tra cả IP và Tác nhân người dùng để xem họ có thay đổi không
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
|| $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
//Something fishy is going on here?
}
Nếu bạn sử dụng session_set_save_handler (), bạn có thể đặt trình xử lý phiên của riêng mình. Ví dụ: bạn có thể lưu trữ các phiên của mình trong cơ sở dữ liệu. Tham khảo các bình luận php.net để biết ví dụ về trình xử lý phiên cơ sở dữ liệu.
Các phiên DB cũng tốt nếu bạn có nhiều máy chủ nếu không, nếu bạn đang sử dụng các phiên dựa trên tệp, bạn sẽ cần đảm bảo rằng mỗi máy chủ web có quyền truy cập vào cùng một hệ thống tệp để đọc / ghi các phiên.
Bạn cần chắc chắn dữ liệu phiên là an toàn. Bằng cách xem php.ini của bạn hoặc sử dụng phpinfo (), bạn có thể tìm thấy các cài đặt phiên. _session.save_path_ cho bạn biết nơi họ được lưu.
Kiểm tra sự cho phép của thư mục và của cha mẹ của nó. Nó không nên công khai (/ tmp) hoặc có thể truy cập bởi các trang web khác trên máy chủ được chia sẻ của bạn.
Giả sử bạn vẫn muốn sử dụng phiên php, Bạn có thể đặt php để sử dụng một thư mục khác bằng cách thay đổi _session.save_path_ hoặc lưu dữ liệu trong cơ sở dữ liệu bằng cách thay đổi _session.save_handler_.
Bạn có thể đặt _session.save_path_ trong php.ini của mình (một số nhà cung cấp cho phép) hoặc cho apache + mod_php, trong tệp .htaccess trong thư mục gốc trang web của bạn :
php_value session.save_path "/home/example.com/html/session"
. Bạn cũng có thể đặt nó vào thời gian chạy với _session_save_path () _.
Kiểm tra hướng dẫn của Chris Shiflett hoặc Zend_Session_SaveHandler_DbTable để đặt và xử lý phiên thay thế.