Làm cách nào để quản lý thời gian phiên trong PHP?

Mô-đun phiên không thể đảm bảo rằng thông tin được lưu trữ trong phiên chỉ được xem bởi người dùng đã tạo phiên. Các biện pháp bổ sung là cần thiết để bảo vệ tính bảo mật của phiên, tùy thuộc vào giá trị được liên kết với nó

Tầm quan trọng của dữ liệu được thực hiện trong phiên cần được đánh giá và có thể triển khai thêm biện pháp bảo vệ; . Ví dụ: để bảo vệ người dùng khỏi một chiến thuật kỹ thuật xã hội đơn giản, cần bật session.use_only_cookies. Trong trường hợp đó, cookie phải được bật vô điều kiện ở phía máy khách, nếu không các phiên sẽ không hoạt động

Có một số cách để rò rỉ ID phiên hiện có cho bên thứ ba. e. g. Tiêm JavaScript, ID phiên trong URL, đánh hơi gói, truy cập vật lý vào thiết bị, v.v. ID phiên bị rò rỉ cho phép bên thứ ba truy cập tất cả các tài nguyên được liên kết với một ID cụ thể. Đầu tiên, các URL mang ID phiên. Nếu có liên kết đến một trang web hoặc tài nguyên bên ngoài, thì URL bao gồm ID phiên có thể được lưu trữ trong nhật ký liên kết giới thiệu của trang web bên ngoài. Thứ hai, kẻ tấn công tích cực hơn có thể lắng nghe lưu lượng mạng. Nếu nó không được mã hóa, ID phiên sẽ chuyển ở dạng văn bản thuần túy qua mạng. Giải pháp là triển khai SSL/TLS trên máy chủ và bắt buộc người dùng phải sử dụng SSL/TLS. HSTS nên được sử dụng để cải thiện an ninh

Ghi chú. Ngay cả HTTPS cũng không thể bảo vệ dữ liệu bí mật mọi lúc. Ví dụ: các lỗ hổng CRIME và Beast có thể cho phép kẻ tấn công đọc dữ liệu. Ngoài ra, lưu ý rằng nhiều mạng sử dụng proxy HTTPS MITM cho mục đích kiểm tra. Những kẻ tấn công cũng có thể thiết lập một proxy như vậy

Quản lý phiên không thích ứng

Trình quản lý phiên của PHP hiện đang thích ứng theo mặc định. Trình quản lý phiên thích ứng chịu thêm rủi ro

Khi được bật và trình xử lý lưu phiên hỗ trợ, ID phiên chưa được khởi tạo sẽ bị từ chối và ID phiên mới được tạo. Điều này ngăn chặn cuộc tấn công buộc người dùng sử dụng ID phiên đã biết. Kẻ tấn công có thể dán liên kết hoặc gửi email có chứa ID phiên. e. g. http://example.com/page.php?PHPSESSID=123456789 nếu được bật, nạn nhân sẽ bắt đầu phiên sử dụng ID phiên do kẻ tấn công cung cấp. giảm thiểu rủi ro này

Cảnh báo

Trình xử lý lưu do người dùng xác định cũng có thể hỗ trợ chế độ phiên nghiêm ngặt bằng cách triển khai xác thực ID phiên. Tất cả các trình xử lý lưu do người dùng xác định phải triển khai xác thực ID phiên

Cookie ID phiên có thể được đặt với tên miền, đường dẫn, chỉ http, bảo mật và kể từ PHP 7. 3, Thuộc tính SameSite. Có quyền ưu tiên được xác định bởi các trình duyệt. Bằng cách sử dụng quyền ưu tiên, kẻ tấn công có thể đặt ID phiên có thể được sử dụng vĩnh viễn. Việc sử dụng sẽ không giải quyết được vấn đề này. giảm thiểu rủi ro này. Với =On, ID phiên chưa khởi tạo sẽ bị từ chối

Ghi chú. Mặc dù giảm thiểu rủi ro quản lý phiên thích ứng, kẻ tấn công có thể buộc người dùng sử dụng ID phiên khởi tạo do kẻ tấn công tạo ra. e. g. tiêm JavaScript. Cuộc tấn công này có thể được giảm nhẹ bằng các khuyến nghị của sách hướng dẫn này. Bằng cách làm theo hướng dẫn này, nhà phát triển nên bật, , sử dụng quản lý phiên dựa trên dấu thời gian và tạo lại ID phiên bằng cách sử dụng session_regenerate_id() với các quy trình được đề xuất. Nếu các nhà phát triển làm theo tất cả những điều trên, ID phiên do kẻ tấn công tạo ra cuối cùng sẽ bị xóa. Khi truy cập vào một phiên lỗi thời xảy ra, nhà phát triển nên lưu tất cả dữ liệu phiên đang hoạt động của người dùng. Vì thông tin này sẽ có liên quan cho một cuộc điều tra tiếp theo. Người dùng phải đăng xuất khỏi tất cả các phiên, tôi. e. yêu cầu họ xác thực lại. Điều này ngăn kẻ tấn công lạm dụng các phiên bị đánh cắp

Cảnh báo

Truy cập vào một phiên lỗi thời không nhất thiết gợi ý một cuộc tấn công. Mạng không ổn định và/hoặc xóa phiên hoạt động ngay lập tức sẽ dẫn đến việc người dùng hợp pháp sử dụng các phiên lỗi thời

Kể từ PHP 7. 1. 0, session_create_id() đã được thêm vào. Chức năng này có thể được vận hành để truy cập tất cả các phiên hoạt động của người dùng một cách hiệu quả bằng cách đặt trước ID phiên bằng ID người dùng. Kích hoạt là rất quan trọng với thiết lập này. Mặt khác, người dùng độc hại có thể đặt ID phiên độc hại cho người dùng khác

Ghi chú. Người dùng trước PHP 7. 1. 0 NÊN sử dụng CSPRNG, e. g. /dev/urandom, hoặc random_bytes() và các hàm băm để tạo ID phiên mới. session_create_id() có chức năng phát hiện xung đột và tạo ID phiên theo cài đặt INI của phiên. Ưu tiên sử dụng session_create_id()

Tái tạo ID phiên

là một giảm thiểu tốt, tuy nhiên không đủ. Các nhà phát triển phải sử dụng như nhau session_regenerate_id() để bảo mật phiên

Tái tạo ID phiên làm giảm nguy cơ ID phiên bị đánh cắp, do đó session_regenerate_id() phải được gọi định kỳ. e. g. Tạo lại ID phiên cứ sau 15 phút cho nội dung nhạy cảm về bảo mật. Ngay cả trong trường hợp ID phiên bị đánh cắp, phiên của cả người dùng hợp pháp và của kẻ tấn công sẽ hết hạn. Nói cách khác, truy cập của người dùng hoặc kẻ tấn công sẽ tạo ra lỗi truy cập phiên lỗi thời

ID phiên phải được tạo lại khi đặc quyền của người dùng được nâng lên, chẳng hạn như sau khi xác thực. session_regenerate_id() phải được gọi trước khi đặt thông tin xác thực thành $_SESSION. (session_regenerate_id() tự động lưu dữ liệu phiên hiện tại để lưu dấu thời gian/v.v. đến phiên hiện tại. ) Đảm bảo chỉ phiên mới chứa cờ được xác thực

Nhà phát triển không được phụ thuộc vào việc hết hạn ID phiên bởi. Những kẻ tấn công có thể truy cập ID phiên của nạn nhân theo định kỳ để tránh hết hạn và tiếp tục khai thác nó, bao gồm cả phiên được xác thực

Thay vào đó, các nhà phát triển phải triển khai quản lý dữ liệu phiên dựa trên dấu thời gian

Cảnh báo

Mặc dù trình quản lý phiên có thể quản lý dấu thời gian một cách rõ ràng nhưng tính năng này không được triển khai. Dữ liệu phiên cũ phải được lưu giữ cho đến khi GC. Đồng thời, các nhà phát triển phải tự đảm bảo rằng dữ liệu phiên lỗi thời sẽ bị xóa. Tuy nhiên, nhà phát triển không được xóa dữ liệu phiên đang hoạt động ngay lập tức. Tôi. e. session_regenerate_id(true); và session_destroy() không bao giờ được gọi cùng nhau cho một phiên đang hoạt động. Điều này nghe có vẻ mâu thuẫn, nhưng đây là yêu cầu bắt buộc

session_regenerate_id() không xóa các phiên lỗi thời theo mặc định. Phiên xác thực lỗi thời có thể có mặt để sử dụng. Các nhà phát triển phải ngăn không cho bất kỳ ai sử dụng các phiên lỗi thời. Họ phải tự cấm truy cập vào dữ liệu phiên lỗi thời bằng cách sử dụng dấu thời gian

Cảnh báo

Việc loại bỏ đột ngột một phiên đang hoạt động sẽ tạo ra các tác dụng phụ không mong muốn. Các phiên có thể biến mất khi có các kết nối đồng thời với ứng dụng web và/hoặc mạng không ổn định

Truy cập độc hại tiềm ẩn không thể bị phát hiện với việc loại bỏ đột ngột các phiên đang hoạt động

Thay vì xóa các phiên lỗi thời ngay lập tức, nhà phát triển phải đặt thời gian hết hạn ngắn hạn (dấu thời gian) trong $_SESSION và cấm tự mình truy cập vào dữ liệu phiên

Nhà phát triển không được cấm truy cập vào dữ liệu phiên cũ ngay sau session_regenerate_id(). Nó phải bị cấm ở giai đoạn sau. e. g. một vài giây sau đối với các mạng ổn định, chẳng hạn như mạng có dây và vài phút sau đối với các mạng không ổn định, chẳng hạn như điện thoại di động hoặc Wi-Fi

Nếu người dùng truy cập phiên lỗi thời (phiên hết hạn), quyền truy cập vào phiên đó sẽ bị từ chối. Bạn cũng nên xóa trạng thái đã xác thực khỏi tất cả các phiên của người dùng vì trạng thái này có khả năng biểu thị một cuộc tấn công

Việc sử dụng và session_regenerate_id() đúng cách có thể gây ra DoS cá nhân với các cookie không thể xóa được do kẻ tấn công đặt. Trong trường hợp này, nhà phát triển có thể mời người dùng xóa cookie và thông báo cho họ rằng họ có thể bị ảnh hưởng bởi sự cố bảo mật. Kẻ tấn công có thể đặt cookie độc ​​hại thông qua ứng dụng web dễ bị tổn thương, plugin trình duyệt bị lộ/xấu xa, thiết bị bị xâm phạm vật lý, v.v.

Cảnh báo

Đừng hiểu lầm về rủi ro DoS. use_strict_mode=On là bắt buộc để bảo mật ID phiên chung. Tất cả các trang web nên kích hoạt use_strict_mode

DoS chỉ có thể xảy ra khi tài khoản bị tấn công. Lỗ hổng tiêm JavaScript trong ứng dụng là nguyên nhân phổ biến nhất

Xóa dữ liệu phiên

Dữ liệu phiên lỗi thời phải không thể truy cập được và bị xóa. Mô-đun phiên hiện tại không xử lý tốt việc này

Dữ liệu phiên lỗi thời nên được xóa càng sớm càng tốt. Tuy nhiên, các phiên hoạt động không được xóa ngay lập tức. Để đáp ứng các yêu cầu đó, nhà phát triển phải tự triển khai quản lý dữ liệu phiên dựa trên dấu thời gian

Đặt và quản lý dấu thời gian hết hạn trong $_SESSION. Cấm truy cập vào dữ liệu phiên đã lỗi thời. Khi phát hiện quyền truy cập vào dữ liệu phiên lỗi thời, bạn nên xóa tất cả trạng thái đã xác thực khỏi phiên của người dùng và buộc họ xác thực lại. Truy cập vào dữ liệu phiên lỗi thời có thể đại diện cho một cuộc tấn công. Để đạt được điều này, các nhà phát triển phải theo dõi tất cả các phiên hoạt động của mọi người dùng

Ghi chú. Truy cập vào một phiên lỗi thời cũng có thể xảy ra do mạng không ổn định và/hoặc truy cập đồng thời vào trang web. e. g máy chủ đã cố đặt ID phiên mới qua cookie, nhưng gói Set-Cookie có thể chưa đến được máy khách do mất kết nối. Một kết nối có thể cấp ID phiên mới bởi session_regenerate_id(), nhưng một kết nối đồng thời khác có thể chưa nhận được ID phiên mới. Do đó, các nhà phát triển phải cấm truy cập vào phiên lỗi thời ở giai đoạn sau. Tôi. e. quản lý phiên dựa trên dấu thời gian là bắt buộc

Tóm lại, dữ liệu phiên không được hủy bằng session_regenerate_id() hoặc session_destroy(), nhưng dấu thời gian phải được sử dụng để kiểm soát quyền truy cập vào dữ liệu phiên. Hãy để session_gc() xóa dữ liệu lỗi thời khỏi bộ lưu trữ dữ liệu phiên

Phiên và khóa

Dữ liệu phiên bị khóa để tránh điều kiện cuộc đua theo mặc định. Khóa là bắt buộc để giữ cho dữ liệu phiên nhất quán trên các yêu cầu

Tuy nhiên, khóa phiên có thể bị kẻ tấn công lạm dụng để thực hiện các cuộc tấn công DoS. Để giảm thiểu nguy cơ tấn công DoS bằng cách khóa phiên, giảm thiểu các khóa. Sử dụng các phiên chỉ đọc khi không cần cập nhật dữ liệu phiên. Sử dụng tùy chọn 'read_and_close' với session_start(). session_start(['read_and_close'=>1]); Đóng phiên càng sớm càng tốt sau khi cập nhật $_SESSION bằng cách sử dụng session_commit()

Mô-đun phiên hiện tại không phát hiện bất kỳ sửa đổi nào của $_SESSION khi phiên không hoạt động. Nhà phát triển có trách nhiệm không sửa đổi $_SESSION khi phiên không hoạt động

Phiên hoạt động

Các nhà phát triển nên theo dõi tất cả các phiên hoạt động cho mọi người dùng. Và thông báo cho họ biết có bao nhiêu phiên hoạt động, từ IP nào (và khu vực), nó đã hoạt động trong bao lâu, v.v. PHP không theo dõi những điều này. Các nhà phát triển phải làm như vậy

Nhiều cách khác nhau để thực hiện điều này tồn tại. Một triển khai khả thi là thiết lập cơ sở dữ liệu theo dõi dữ liệu cần thiết và lưu trữ mọi thông tin liên quan. Vì dữ liệu phiên được GCed, các nhà phát triển phải quan tâm đến dữ liệu GCed để duy trì tính nhất quán của cơ sở dữ liệu phiên hoạt động

Một trong những cách triển khai đơn giản nhất là "ID phiên có tiền tố ID người dùng" và lưu trữ thông tin bắt buộc trong $_SESSION. Nhiều cơ sở dữ liệu có hiệu suất tốt để chọn tiền tố chuỗi. Nhà phát triển CÓ THỂ sử dụng session_regenerate_id() và session_create_id() cho việc này

Cảnh báo

Không bao giờ sử dụng dữ liệu bí mật làm tiền tố. Nếu ID người dùng là bí mật, hãy cân nhắc sử dụng hash_hmac()

Cảnh báo

Việc bật là bắt buộc đối với thiết lập này. Đảm bảo nó được kích hoạt. Nếu không, cơ sở dữ liệu phiên hoạt động có thể bị xâm phạm

Quản lý phiên dựa trên dấu thời gian là bắt buộc để phát hiện quyền truy cập vào các phiên lỗi thời. Khi phát hiện quyền truy cập vào một phiên lỗi thời, các cờ xác thực sẽ bị xóa khỏi tất cả các phiên hoạt động của người dùng. Điều này ngăn những kẻ tấn công tiếp tục khai thác các phiên bị đánh cắp

Phiên và Tự động đăng nhập

Nhà phát triển không được sử dụng ID phiên dài hạn để đăng nhập tự động vì điều này làm tăng nguy cơ phiên bị đánh cắp. Nhà phát triển nên triển khai tính năng đăng nhập tự động

Sử dụng khóa băm một lần an toàn làm khóa đăng nhập tự động bằng setcookie(). Sử dụng hàm băm an toàn mạnh hơn SHA-2. e. g. SHA-256 trở lên với dữ liệu ngẫu nhiên từ Random_bytes() hoặc /dev/urandom

Nếu người dùng chưa được xác thực, hãy kiểm tra xem khóa đăng nhập tự động một lần có hợp lệ hay không. Trong trường hợp nó hợp lệ, hãy xác thực người dùng và đặt khóa băm một lần an toàn mới. Khóa đăng nhập tự động chỉ được sử dụng một lần, tôi. e. không bao giờ sử dụng lại khóa đăng nhập tự động, luôn tạo khóa mới

Khóa đăng nhập tự động là khóa xác thực có tuổi thọ cao, khóa này cần được bảo vệ càng nhiều càng tốt. Sử dụng các thuộc tính cookie đường dẫn/httponly/secure/SameSite để bảo mật nó. Tôi. e. không bao giờ truyền khóa đăng nhập tự động trừ khi được yêu cầu

Nhà phát triển phải triển khai các tính năng vô hiệu hóa đăng nhập tự động và xóa cookie khóa đăng nhập tự động không cần thiết

Tấn công CSRF (Cross-Site Request Forgeries)

Phiên và xác thực không bảo vệ chống lại các cuộc tấn công CSRF. Các nhà phát triển phải tự triển khai bảo vệ CSRF

output_add_rewrite_var() có thể được sử dụng để bảo vệ CSRF. Tham khảo trang hướng dẫn để biết thêm chi tiết

Ghi chú. PHP trước 7. 2. 0 sử dụng cùng bộ đệm đầu ra và cài đặt INI làm trans sid. Do đó, hãy sử dụng output_add_rewrite_var() với PHP trước phiên bản 7. 2. 0 không được khuyên

Hầu hết các khung ứng dụng web đều hỗ trợ bảo vệ CSRF. Tham khảo hướng dẫn sử dụng khung ứng dụng web để biết thêm chi tiết

Kể từ PHP 7. 3 có thể đặt thuộc tính SameSite cho cookie phiên. Đây là một biện pháp bổ sung có thể giảm thiểu lỗ hổng CSRF