0

私はいくつかの画像検証を行いました。ユーザーは、動的に生成された画像からコードを入力する必要があります。

このコードは、メインの 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;

これは、セッションにキーを保存する方法です。

問題は、イメージがブロックされる可能性があり、セッション キーが最後に保存された結果から変更されないことです。これは大きな脅威を意味します。可能な保護または回避策があるのだろうか?

質問とセキュリティを理解している場合にのみ回答してください:-)

4

2 に答える 2

1

ブロックされたリクエストよりもキャッシュに注意する必要があります。Cache-Control背景画像は、ヘッダーなどを含めるまで更新されない場合があります。

さらに重要なことは、リプレイを防ぐことです。そのためには、次のものが必要です。

  • タイムスタンプ値。また、キャプチャ検証で古い値の受け入れを拒否するようにします。

  • 1 つまたは 2 つの検証が成功した後、captcha セッションの状態をクリアします。

背景画像がロードされていない (「ブロックされている」) ということは、そもそもセッション ストアに有効なトークンがないことを意味します。検証ロジックが適切に設計されていない限り、これは問題ではありません。

最後に、画像にランダムな線があると、キャプチャの有効性は向上しません。フォーム構造が珍しいのと同じくらい効果的です。スパイダーがカスタム バリエーションに適応すると、回避するのは非常に簡単です。偽のセキュリティは、そのあいまいさにあります。それほど優れた学習体験ではありませんが、既製のキャプチャ スクリプトを使用することをお勧めします。

于 2012-06-28T00:54:51.110 に答える
0

結果を保存するだけでなく、タイムスタンプも保存してみませんか。そうすれば、おそらく 10 分で結果を失効させることができます。

また、フォームからの送信を検証するコードを一部に配置して、成功したかどうかに関係なく、そのセッション変数をクリアします。そうすれば、再度提出したい場合は、新しい結果を入力する必要があります。

于 2012-06-28T00:56:33.007 に答える