简体   繁体   中英

PHP: any way to secure a session variable / captcha?

I've made some image validation. The user has to enter the code from the dynamically generated image.

This code is being used in the main php file:

@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;

Note this:

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

This is how I call the generated image. And this is it's content:

<?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);
}
?>

Note:

$_SESSION['result'] = $pass;

This is how I store key in the session.

Now, the problem is, the image can be potentially blocked, and the session key will not change from the last stored result. This means a huge threat. I wonder if there any protection or workaround possible?

Please answer only if you understand the question and security :-)

You should be more concerned about caching than about blocked requests. Background images might not be refreshed until you include some Cache-Control headers etc.

What's more important is to prevent replays. To do so, you should have:

  • A timestamp value. And make the captcha validation refuse to accept older values.

  • Clear the captcha session state after one or two successful validations.

The background image not being loaded ("blocked") just means you won't have a valid token in the session store to begin with. That's not a problem, unless your verification logic is badly designed.

Lastly, the effectiveness of your captcha doesn't increase with random lines in the image. It's just as effective as uncommon your form structure is. Once a spider adapts to your custom variation, it's pretty simple to circumvent. The faux security lies in its obscurity. While not such a great learning experience, a readymade captcha script might be advisable.

Besides storing a result, why not also store a time stamp. That way, you can expire the result in maybe ten minutes.

Also put some codes in the part that validate the submission from the form to clear that session variable regardless of whether it is successful or not. That way, if they want to submit again they will need to enter the new result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM