2010-01-09 21 views
15

Tôi là người mới bắt đầu làm việc trên tập lệnh đăng nhập bằng PHP. Đây là tuyên bố mã thông báo biểu mẫu mà tôi có cho đến thời điểm này:Sử dụng mã thông báo biểu mẫu PHP và xử lý

$_SESSION["form_token"] = md5(rand(time(), true)) ; 

Tuyên bố được phát hành ngay sau khi người dùng cho biết rằng họ muốn đăng nhập.

Hiểu biết hạn chế của tôi là mục đích mã thông báo là xác định người dùng duy nhất tại một thời điểm duy nhất và cải trang thông tin mã thông báo biểu mẫu.

Sau đó mọi thứ trở nên mờ. Dưới đây là 3 câu hỏi mở của tôi:

  1. Khi nào là thời gian tốt nhất để "kiểm tra" mã thông báo biểu mẫu cho mục đích bảo mật?

  2. Làm cách nào để kiểm tra?

  3. Khi nào, nếu bao giờ, tôi có "hủy" mã thông báo biểu mẫu không? (IOW, hình thức thẻ sẽ ở lại "hoạt động" cho đến khi người dùng đăng xuất?

+2

FYI MD5 có phần hạn chế và nếu bạn cần phải tạo ra một chuỗi ngẫu nhiên tôi đề nghị bạn sử dụng này để thay thế: $ id = sha1 (mt_rand()); Nếu bạn sử dụng rand() bạn chỉ nhận được 32.000 kết hợp có thể. – TravisO

+0

liên quan: http://stackoverflow.com/questions/5111007/does-php-have-an-authenticity-token-like-rails – baptx

Trả lời

12

Không cần phải làm những gì bạn đang cố gắng. Khi bạn bắt đầu một phiên trong PHP với session_start() một SESSIONID duy nhất đã được tạo ra cho bạn. Bạn nên không phải đang đặt thông tin này trên biểu mẫu. Nó được xử lý thông qua cookie theo mặc định. Ngoài ra, bạn cũng không cần phải kiểm tra SESSIONID, điều đó lại được xử lý cho bạn.

Bạn chịu trách nhiệm chứng thực người sử dụng và lưu trữ danh tính thực của họ (ví dụ $ _SESSION [ 'user_id'] = $ userId trong phiên. Nếu người dùng đăng xuất bạn phá hủy phiên họp của họ với session_destroy.

Bạn nên đảm bảo session_start() là một trong số đầu tiên mọi thứ cho tất cả các trang trong trang web của bạn.

Dưới đây là một ví dụ cơ bản:

<?php 
session_start(); // starts new or resumes existing session 
session_regenerate_id(true); // regenerates SESSIONID to prevent hijacking 

function login($username, $password) 
{ 
    $user = new User(); 
    if ($user->login($username, $password)) { 
     $_SESSION['user_id'] = $user->getId(); 
     return true; 
    } 
    return false; 
} 

function logout() 
{ 
    session_destroy(); 
} 

function isLoggedIn() 
{ 
    return isset($_SESSION['user_id']); 
} 

function generateFormHash($salt) 
{ 
    $hash = md5(mt_rand(1,1000000) . $salt); 
    $_SESSION['csrf_hash'] = $hash 
    return $hash; 
} 

function isValidFormHash($hash) 
{ 
    return $_SESSION['csrf_hash'] === $hash; 
} 

Edit: Tôi hiểu lầm câu hỏi ban đầu. Tôi đã thêm các phương thức liên quan ở trên để tạo và xác nhận các băm biểu mẫu;

Xin vui lòng xem các nguồn sau:

+0

Có điều tôi không hiểu. Tôi cũng sử dụng phiên php cho thẻ, nhưng mỗi lần tôi sửa đổi một phiên, tất cả chúng đều được sửa đổi ("ngày sửa đổi" của tất cả các thay đổi tập tin tmp). Có bất kỳ kết nối nào giữa các phiên xác định những người dùng khác nhau không? – Sthe

18

này là để ngăn chặn CSRF tấn công

http://en.wikipedia.org/wiki/Cross-site_request_forgery

một trang web độc hại về mặt lý thuyết có thể hiển thị một hình thức mà bài viết để ứng dụng của bạn có thể chứa các hướng dẫn gây ra vi phạm dữ liệu hoặc một số hành động không mong muốn. Người dùng có thể bị lừa khi gửi biểu mẫu mà ứng dụng sẽ chấp nhận vì người dùng đã đăng nhập. trang web và không phải trang web nào khác.

kiểm tra HTTP_REFERER thường đủ tốt, nhưng không hoàn thành giải pháp (ví dụ https sẽ không gửi chuỗi liên kết giới thiệu).

nếu bạn thực sự muốn bảo mật tất cả biểu mẫu bằng mã thông báo, bạn có thể tạo một số chức năng tiện lợi như emitToken() và checkToken() để làm cho trang web hoạt động trên toàn trang web.

một số ví dụ:

http://phpsec.org/projects/guide/2.html

http://www.rodsdot.com/php/CSRF_Form_Protection.php

+2

HTTP_REFERER KHÔNG đáng tin cậy, không bao giờ dựa vào nó vì nó có thể dễ dàng được chỉnh sửa! – Heitor

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