2008-08-02 40 views
125

Một số nguyên tắc để duy trì bảo mật phiên có trách nhiệm với PHP là gì? Có thông tin trên toàn bộ trang web và đã đến lúc tất cả đã hạ cánh ở một nơi!Bảo mật phiên PHP

Trả lời

88

Có một vài điều cần làm để giữ phiên của bạn an toàn:

  1. Sử dụng SSL khi chứng thực người dùng hoặc thực hiện các hoạt động nhạy cảm.
  2. Tạo lại id phiên bất cứ khi nào mức độ bảo mật thay đổi (chẳng hạn như đăng nhập). Bạn thậm chí có thể tạo lại id phiên mỗi yêu cầu nếu bạn muốn.
  3. Có phiên thời gian ra
  4. Không sử dụng hình cầu đăng ký
  5. Lưu trữ chi tiết xác thực trên máy chủ. Tức là, đừng gửi các chi tiết như tên người dùng trong cookie.
  6. Kiểm tra $_SERVER['HTTP_USER_AGENT']. Điều này cho biết 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, vv (đó là trường hợp trong môi trường của chúng tôi ở đây).
  7. Khóa xuống truy cập vào các buổi trên hệ thống tập tin hoặc sử dụng phiên tùy chỉnh xử lý
  8. Đối với các hoạt động nhạy cảm xem xét đòi hỏi phải đăng nhập người dùng cung cấp thông tin chi tiết authenication của họ một lần nữa
+15

Chỉ sử dụng SSL cho một số thao tác, trừ khi bạn có các phiên riêng biệt cho lưu lượng được mã hóa và không được mã hóa. Nếu bạn sử dụng một phiên duy nhất trên HTTPS và HTTP, kẻ tấn công sẽ ăn cắp nó theo yêu cầu không phải HTTPS đầu tiên. – Kornel

+0

Tôi đồng ý với porneL. Ngoài ra, đối với số 6, nếu kẻ tấn công có id phiên của bạn, họ cũng sẽ không có quyền truy cập vào tác nhân người dùng của bạn không? – Chad

+0

Nếu bạn tạo lại id phiên thì id phiên mà kẻ tấn công đánh cắp trên yêu cầu không phải HTTPS là vô dụng. – grom

15

Một hướng dẫn là gọi số 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 việc chiếm đoạt phiên.

11

Tôi nghĩ một trong những vấn đề chính (được giải quyết trong PHP 6) là register_globals. Hiện tại, một trong những phương pháp tiêu chuẩn được sử dụng để tránh register_globals là sử dụng các mảng $_REQUEST, $_GET hoặc $_POST.

Cách "đúng" để thực hiện (như 5.2, mặc dù đó là một lỗi nhỏ ở đó, nhưng ổn định là 6, sắp có) là qua filters.

Vì vậy, thay vì:

$username = $_POST["username"]; 

bạn sẽ làm gì:

$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING); 

hoặc thậm chí chỉ:

$username = filter_input(INPUT_POST, 'username'); 
+2

này không có liên quan đến câu hỏi nào cả. –

+5

Thật sao? Vậy tại sao trong câu trả lời được chấp nhận họ đề cập đến không sử dụng globals đăng ký? Sẽ không, như xa như hầu hết các nhà phát triển run-of-the-mill có liên quan, đăng ký globals và hình thức xử lý biến thuộc ô dù của "phiên" ngay cả khi nó không phải là một phần kỹ thuật của "phiên" đối tượng? – cmcculloh

+0

-1 Điều này không trả lời được câu hỏi. – Tomas

3

này là khá tầm thường và hiển nhiên, nhưng hãy chắc chắn 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 một cách rõ ràng, vì vậy bộ hẹn giờ có thể được đặt để thực hiện việc này.

Đây là một tốt tutorial trên setTimer() và clearTimer().

3

Vấn đề chính với phiên PHP và bảo mật (bên cạnh việc chiếm đoạt 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 tệp trong thư mục tạm thời của hệ điều hành. Nếu không có bất kỳ suy nghĩ hoặc lập kế hoạch đặc biệt nào, đây là một thư mục có thể đọc được trên thế giới để 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ủ.

Để duy trì phiên trên nhiều máy chủ. Tại thời điểm đó, sẽ tốt hơn khi chuyển đổi PHP sang các phiên xử lý người dùng mà nó gọi các hàm được cung cấp của bạn tới 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 sử dụng máy chủ chia sẻ vì nó sẽ cho phép bạn lưu nó trong cơ sở dữ liệu mà bạn thường kiểm soát nhiều hơn hệ thống tập tin.

2

tôi sẽ kiểm tra cả IP và User Agent để xem nếu họ thay đổi

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT'] 
    || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR']) 
{ 
    //Something fishy is going on here? 
} 
+5

IP có thể thay đổi hợp pháp nếu người dùng đứng đằng sau trang trại proxy cân bằng tải. – Kornel

+2

Và user_agent có thể thay đổi mỗi lần người dùng nâng cấp trình duyệt của họ. – scotts

+3

@scotts Tôi đồng ý với phần IP nhưng để nâng cấp trình duyệt, bạn sẽ đặt phiên khi họ đăng nhập để tôi không thấy cách họ nâng cấp lên trình duyệt đó mà không tạo phiên mới khi họ đăng nhập lại. – JasonDavis

5

Sử dụng địa chỉ IP là không thực sự là ý tưởng tốt nhất trong 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 biệt 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 trên 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 đó vẫn là ý tưởng hay.

2

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 bạn trong cơ sở dữ liệu. Tham khảo php.net bình luận cho các ví dụ về một trình xử lý phiên cơ sở dữ liệu.

Phiên DB cũng tốt nếu bạn có nhiều máy chủ 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 đều có quyền truy cập vào cùng một hệ thống tệp để đọc/ghi các phiên.

2

Bạn cần phải 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 chúng được lưu.

Kiểm tra quyền của thư mục và của cha mẹ. Nó không được công khai (/ tmp) hoặc có thể truy cập được 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 (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 của trang web: php_value session.save_path "/home/example.com/html/session". Bạn cũng có thể thiết lập nó tại thời gian chạy với _session_save_path() _.

Kiểm tra Chris Shiflett's tutorial hoặc Zend_Session_SaveHandler_DbTable để đặt và xử lý phiên thay thế.

11

My hai (hoặc nhiều hơn) cent:

  • ủy thác không có ai
  • Lọc đầu vào, thoát ra (cookie, dữ liệu phiên là đầu vào của bạn quá)
  • Tránh XSS (giữ HTML của bạn cũng được hình thành , hãy nhìn vào PHPTAL hoặc HTMLPurifier)
  • Defense in depth
  • Đừng lộ dữ liệu

Có một cuốn sách nhỏ nhưng hay về chủ đề này: Essential PHP Security by Chris Shiflett.

Essential PHP Security 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à chương mẫu.

Bạn có thể sử dụng kỹ thuật nêu trên (IP & UserAgent), được mô tả ở đây: How to avoid identity theft

+0

+1 cho phòng ngừa XSS. Nếu không có điều đó là không thể bảo vệ chống lại CSRF, và do đó ai đó có thể "cưỡi" phiên mà không nhận được ID phiên. – Kornel

3

tôi đặt phiên tôi lên như this-

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 đề nằm trong 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();  
} 
3

php.ini

session.cookie_httponly = 1 
change session name from default PHPSESSID 

eq Apache thêm tiêu đề:

X-XSS-Protection 1 
+0

Bạn có thể xây dựng? – domino

+0

httpd.conf -> Tiêu đề đặt X-XSS-Protection "1" user956584

+0

Hãy lưu ý rằng 'X-XSS-Protection' không phải là 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ể được khai thác, làm cho nó tồi tệ hơn trước. – Pacerier