2010-04-08 41 views
8

Tôi điều hành một trang web trò chơi để tôi có nhiều người dùng đăng nhập và họ có thể làm những việc nhất định sau mỗi hai phút.Mã xác minh PHP CAPTCHA

Tôi có một hệ thống CAPTCHA ở những nơi, và đối với một số thứ, nó sẽ luôn yêu cầu mã, và đối với những thứ khác, nó sẽ hỏi 10 phút một lần.

Tôi đã có một số người chơi sử dụng tính năng tự động gửi trên Opera và hệ thống CAPTCHA của tôi sẽ chặn chúng.

Câu hỏi của tôi là, làm cách nào để giảm thiểu số lần tôi yêu cầu mã, nhưng vẫn ngăn mọi người sử dụng tính năng tự động gửi này?

+0

Tôi nghĩ tôi có ý tưởng về giải pháp không phải hình ảnh xác thực nhưng tôi cần thêm chi tiết. Làm cách nào để họ sử dụng tính năng tự động gửi? Bạn muốn ngăn họ làm gì? Gửi quá nhanh và quá thường xuyên, hoặc gửi đi khi rời khỏi bàn phím? – naugtur

+0

Tôi đã quyết định đăng ý tưởng của mình ngay bây giờ, nhưng Bạn vẫn có thể trả lời – naugtur

Trả lời

6

Nếu tôi hiểu chính xác tác vụ này không yêu cầu hình ảnh xác thực. Tôi giả sử Bạn muốn xem liệu người dùng có nhấp vào chính mình không, ngồi trước máy tính của mình.

ý tưởng mới

Đặt hình ảnh nhiều nộp vào mẫu của bạn:

<input type="image" name="send1" src="buttons.php?i=1" /> 
... 
<input type="image" name="send8" src="buttons.php?i=8" /> 

khi tạo một hình thức lấy một số ngẫu nhiên giữa 1 và 8 và lưu nó trong $_SESSION['submitnumber']. tạo hai hình ảnh có kích thước giống nhau - một hình ảnh trống chứa đầy nền Mặc định của bạn dưới dạng, hình ảnh khác trông giống như nút gửi. tạo buttons.php rằng hình ảnh sẽ ra với mã này:

header("Content-Type: image/jpeg"); 
flush(); 
readfile($filename); 

và trở về hình ảnh sản phẩm nào nếu $_GET[i]!=$_SESSION['submitnumber'] khác trả lại hình ảnh nộp.

Chấp nhận các hình thức nếu imagesubmit đúng được nhấp (trình duyệt sẽ gửi Bạn coords như send1X khi người dùng nhấp vào nút)

Đó là một loại hình ảnh xác thực, nhưng mọi người sẽ không biết;)

ý tưởng cũ

Bạn cần hai điều:

Tạo thẻ cho các hình thức đó là khá độc đáo.

đặt <input type="hidden" name="timertoken" value="someweirdstring" /> và tạo chuỗi "someweirdstring" thành md5 băm của một số thứ (tên người dùng và thời gian) - điều đơn.Tôi có thể giải thích về điều này, nhưng đây là một mã thông báo mẫu cơ bản để chặn các cuộc tấn công an toàn và CSRF. Mã thông báo được xác minh sau khi đăng.

dụ:

Đây là không một việc thực hiện đặc trưng của cơ chế mã thông báo, nhưng nó sẽ là đủ.

$token=generatesomerandomtext(); 
$_SESSION['token']=$token; 

//... somewhere later when outputing forms:  
echo '<input type="hidden" name="token" value="'.$token.'" />'; 

//and when it comes back: 
if($_POST['token']==$_SESSION['token']) { 
    //it's ok 
    } 

và đó là tất cả những gì bạn cần. ví dụ đơn giản này tạo ra một mã thông báo duy nhất cho mỗi trang và đưa vào biểu mẫu. Nó không phụ thuộc vào thời gian và không sử dụng md5, nhưng lưu trữ mã thông báo trong phiên. Để tự động gửi biểu mẫu được chấp nhận, người đó phải sử dụng biểu mẫu Bạn đã tạo hoặc sao chép mã thông báo.

Ví dụ mã thông báo biểu mẫu thực sẽ giống như sau: $ token = md5 ($ username.'some văn bản bí mật '. $ Date. $ TimeRoundedTo10Minutes);

//... somewhere later when outputing forms:  
echo '<input type="hidden" name="token" value="'.$token.'" />'; 

//and when it comes back: 
if(
($_POST['token']==md5($username.'some secret text'.$date.$timeRoundedTo10Minutes)) || 
($_POST['token']==md5($username.'some secret text'.$date.$timeRoundedTo10Minutes-10minutes))) { 
    //it's ok 
    } 

Tại sao lại là tên người dùng? Bởi vì nó loại bỏ khả năng sử dụng mã thông báo của một người dùng để tấn công người dùng khác Tại sao văn bản bí mật (được gọi là 'muối')? Bởi vì ai đó có thể gắn tên của người dùng khác với thời gian và làm md5, nhưng không đoán được muối anh ta không thể. Tại sao lại có hai so sánh? Bởi vì nếu bây giờ là 22:44:59 - mã thông báo được tạo ra với 22:40 và nếu người dùng gửi nó là 22:45:30 vì vậy nó được làm tròn đến 22:50 và nó khớp với mã thông báo chỉ khi bạn mang nó trở lại 10 phút .

Đó là ví dụ cơ bản. Để tham khảo, hãy xem this câu hỏi.

Thay đổi nút gửi của bạn thành <input type="image" ... khi nó đăng các tọa độ x và y của vị trí nút được nhấp. Tôi không biết ai đã đưa ra điều này trong đặc điểm kỹ thuật, nhưng đây là lần đầu tiên nó có thể được sử dụng! :)

Bây giờ để xem liệu người dùng đã tự bấm vào Bạn chỉ cần xem liệu tọa độ có hiện diện không (gửi cổ điển sẽ không gửi chúng) và chặn việc hack đơn giản này Bạn cũng có thể nhớ x và y cuối cùng trong trình phát phiên và so sánh. Thật khó để hack nó để gửi các coords khác nhau mỗi lần.

Mã thông báo biểu mẫu ở đó để ngăn người dùng chuẩn bị bản sao biểu mẫu của bạn với các trường ngẫu nhiên sẽ mô phỏng tọa độ nhấp chuột. Nếu mã thông báo thay đổi mỗi lần thật khó để ghi đè trường biểu mẫu.

Tính năng này vẫn có thể bị tấn công bởi chức năng người dùng nhưng khó hơn nhiều. Và nếu bạn đã thêm một hình ảnh xác thực một lần trong một giờ, không ai có thể bận tâm khi viết các tập lệnh chỉ có thể giúp trong một giờ và sau đó phá vỡ (và yêu cầu một số nỗ lực và kiến ​​thức).

+0

Không phải ai cũng sử dụng chuột ... – ntd

+0

Tốt hơn hết là mong đợi, hơn là không làm gì, phải không? Nếu họ sử dụng bàn phím, họ sẽ thấy cùng một hình ảnh xác thực mà họ nhận được ngay bây giờ. VÀ nếu bạn viết một dòng javascript mà ngừng gửi vào nhập nó lá ra chỉ lynx-alikes. Chúng không được hỗ trợ nếu Hinek sử dụng hình ảnh xác thực, đúng không? – naugtur

+0

Bạn có thể viết thêm về các mã thông báo này không. Đôi khi tôi có nhiều biểu mẫu trên một trang, điều này có gây ra sự cố không? Và bạn có nghĩa là tạo ra các mã thông báo và lưu nó trong cơ sở dữ liệu của tôi, và thêm nó vào một hình thức và sau đó kiểm tra chúng chống lại eachother? hoặc chỉ lưu trữ mã nhận được cuối cùng và kiểm tra xem họ có đăng cùng một mã thông báo hai lần không? – Juddling

3

Tùy thuộc vào dữ liệu bạn nhận được, bạn có thể thu thập các bằng chứng cho thấy người gọi là người dùng. Chỉ hỏi CAPTCHA, nếu người gọi có vẻ là một bot.

Evidents có thể là:

  • user agent (không đáng tin cậy, bởi vì Opera có thể giả mạo này)
  • khoảng các trình được kích hoạt (chính xác hơn các cuộc gọi chạm tức là mỗi 2 phút càng khả năng nó là một bot)
  • nếu dữ liệu của bạn cho phép kiểm tra trả lại mẫu nó có thể là một điều hiển nhiên, quá
  • ...