2012-06-28 51 views
0

我做了一些圖像驗證。用戶必須從動態生成的圖像中輸入代碼。PHP:以任何方式來保護會話變量/ captcha?

此代碼是在主PHP文件正在使用:

@session_start(); 
if (isset($_POST['session_pw'])&&$_SESSION['result']==$_POST['security_im']) { 
    $_SESSION['pw']=$_POST['session_pw']; 
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR']; 
} 
if ($_SESSION['pw']=='mypassword'&&$_SESSION['ip'] == $_SERVER['REMOTE_ADDR']){ 

     // OK we are in. 
    // Otherwise display a login form: 
}else echo <<<EOD 
    <form method="POST"> 
    <font color="blue"> Authorization is required:</font><br> 
    <input type="text" name="security_im" style="text-align:right;padding-right:1px;background-repeat:no-repeat;background-image:url(../imagecheck.php)"><br> 
    <input type="password" name="session_pw" style="text-align:right;padding-right:1px"><br> 
    <input type="submit" style="margin:0px"> 
    </form> 
EOD; 

注意這一點:

background-image:url(../imagecheck.php) 

這是我如何調用生成的圖像。這是它的內容:

<?php 
session_start(); 
create_image(); 
exit(); 

function create_image() { 
    $md5 = ""; 
    while (strlen($md5) == 0) { 
     $md5 = md5(mt_rand()); 
     $md5 = preg_replace('/[^0-9]/', '', $md5); 
    } 
    $pass = substr($md5, 10, 5); 
    $_SESSION['result'] = $pass; 
    $width = 60; 
    $height = 20; 
    $image = ImageCreate($width, $height); 

    //We are making three colors, white, black and gray 
    $clr[1] = ImageColorAllocate($image, 204, 0, 204); 
    $clr[2] = ImageColorAllocate($image, 0, 204, 204); 
    $clr[3] = ImageColorAllocate($image, 204, 204, 0); 

    $R = rand(1, 3); 
    $black = ImageColorAllocate($image, 255, 255, 255); 
    $grey = ImageColorAllocate($image, 204, 204, 204); 

    //Make the background black 
    ImageFill($image, 0, 0, $black); 

    //Add randomly generated string in white to the image 
    ImageString($image, 5, 7, 2, $pass, $clr[$R]); 

    //Throw in some lines to make it a little bit harder for any bots to break 
    imageline($image, 0, 0, $width - 2, $height - 2, $grey); 
    imageline($image, 0, $height - 2, $width - 2, 0, $grey); 
    ImageRectangle($image, 0, 0, $width - 1, $height - 1, $grey); 

    //Tell the browser what kind of file is come in 
    header("Content-Type: image/jpeg"); 
    //Output the newly created image in jpeg format 
    ImageJpeg($image, null, 80); 
    //Free up resources 
    ImageDestroy($image); 
} 
?> 

注:

$_SESSION['result'] = $pass; 

這是我如何存儲在會話密鑰。

現在,問題是,圖像可能被阻止,並且會話密鑰不會從上次存儲的結果更改。這意味着巨大的威脅。我想知道是否有任何保護或解決方法?

如果你瞭解:-)

+0

驗證碼不是「安全」功能。他們是行爲或權限邏輯。 – mario

+0

您是否在每一個網頁上使用captcha?如果圖片被阻止,他們將無法驗證驗證碼。如果會話密鑰在提供圖像後相同,則知道它已被阻止。如果他們關閉了圖像呢?或有人竊取圖像? – Anthony

回答

1

問題和安全你應該更關心緩存比約被禁止的請求,請唯一的答案。背景圖片可能不會刷新,直到您包含一些Cache-Control標題等。

更重要的是防止重放。爲此,您應該有:

  • 時間戳記值。並使驗證碼驗證拒絕接受較舊的值。

  • 在一次或兩次成功驗證後清除驗證碼會話狀態。

背景圖像沒有被加載(「封鎖」)只是意味着你不會在會話存儲有效令牌開始。這不是問題,除非您的驗證邏輯設計得不好。

最後,驗證碼的有效性不會隨圖像中的隨機線條增加。它的效果與您的表單結構不同。一旦蜘蛛適應你的習俗變化,這很容易規避。虛假的安全在於它的默默無聞。雖然沒有這麼好的學習體驗,但現成的驗證碼腳本可能是可取的。

0

除了存儲結果,爲什麼不存儲時間戳。這樣,您可能會在10分鐘內結束結果。

還要在驗證表單提交的部分放一些代碼來清除會話變量,而不管它是否成功。這樣,如果他們想再次提交,他們需要輸入新的結果。