ZZEE Human Pictcha - Web Spam Protection (Captcha) for PHP and Perl

© Copyright 2005 ZZEE, www.zzee.com. Version 1.0.4.


1. Introduction
2. Requirements and compatibility
       2.1. Tested configurations
3. Installation
       3.1. PHP Interface
       3.2. Perl Interface
4. Adding Human Pictcha verification to your forms
       4.1. Common part
       4.2. PHP
       4.3. Perl
       4.4. Pure HTML files
       4.5. Customizing the look
5. Security
       5.1. Protection from code attacks
       5.2. Defeating Human Pictcha
6. Miscellaneous
       6.1. Fonts
       6.2. Evaluating Human Pictcha completion rate
       6.3. Demo version
7. References

1. Introduction

ZZEE Human Pictcha is a protection in a form of an image (a "captcha"), which can be embedded inside your web forms, and which will filter out various bots, such as spambots or passwordbots, and at the same time it should be fairly easy for a human being to pass the test. If you have a blog where visitors can leave comments, a forum that suffers from spam, a resource being attacked by hackers which are trying to find the passwords by the brute force attack, or any other web resource abused by spammers, Human Pictcha is a solution.

ZZEE Human Pictcha has the following features, which makes it the perfect choice for the captcha protection:

2. Requirements and compatibility

Your website must have the following: Additionally, if you need Perl interface support, then the requirements are like above plus:

2.1. Tested configurations

The following configurations were tested:

3. Installation

3.1. PHP Interface

3.2. Perl Interface

Perl interface uses internally the console interface via zzhpConsole.php file. So you must have PHP CLI support.

4. Adding Human Pictcha verification to your forms

4.1. Common part

This process involves two steps:

Both things are automatically handled by the PHP or Perl interface of Human Pictcha, so your task is easy.

Human Pictcha adds the following input fields to any form that it is protecting. The names were selected to avoid possible name clash with your form parameters names:

zzhpSession Hidden field, passes unique session information
zzhpClearText Text field, passes the code entered by the user

4.2. PHP

Please refer to file "test/zzhpTest.php" as a sample implementation.

  1. You need to require file "zzhpInterface.php" somewhere at the top of your PHP file(s). You need to provide the correct path to it.
    require_once 'zzhp/zzhpInterface.php';
  2. Inside that part of your code, which generates a web form, you need to insert the following PHP code:
    echo zzhpCreateRequestHTML();
    The code should go inside your form, between <form> and </form> tags.
  3. And finally, inside your form processing / input validation routine you need to insert a call to the function zzhpVerifyResponse:
    $errorMessage = '';
    if ($errorCode = zzhpVerifyResponse($zzhpSession, $zzhpClearText, $_SERVER['REMOTE_ADDR'], $errorMessage))
    {
        if ($errorCode == 111)
        {
            // The text submitted doesn't match
        }
        else
        {
            // Something else is wrong, see $errorMessage
        }
    }
    else
    {
        // user passed the verification
    }

    Note that all parameters to zzhpVerifyResponse should be passed not being escaped by PHP magic quotes (many PHP setups by default escape the values). If your PHP setup escapes all input, you need to get rid of it (for example, like this is done in the file "test/zzhpTest.php"): if function get_magic_quotes_gpc() returns true, then do stripslashes() for all of the parameters involved. Please refer to Security section for more information.

    Note that function zzhpVerifyResponse doesn't return a boolean value, it returns 0 if everything is OK, and an integer error code otherwise.

More information about these two functions are available inside "zzhpInterface.php".

4.3. Perl

Please refer to file "test/zzhpTest.pl" as a sample implementation.

  1. At the setup stage, you should have already configured the settings at the top of the file "zzhpInterface.pl".
  2. You need to require file "zzhpInterface.pl" somewhere at the top of your Perl file(s). You need to provide the correct path to it.
    require('zzhp/zzhpInterface.pl');
  3. Inside that part of your code, which generates a web form, you need to insert the following Perl code:
    print zzhpCreateRequestHTML($ENV{'REMOTE_ADDR'});
    The code should go inside your form, between <form> and </form> tags.
  4. And finally, inside your form processing / input validation routine you need to insert a call to the function zzhpVerifyResponse:
    my $errorMessage = '';
    my $errorCode = 0;
    if ($errorCode = zzhpVerifyResponse($q->param('zzhpSession'), $q->param('zzhpClearText'), $ENV{'REMOTE_ADDR'}, \$errorMessage))
    {
        if ($errorCode == 111)
        {
            # The text submitted doesn't match
        }
        else
        {
            # Something else is wrong, see $errorMessage
        }
    }
    else
    {
        # user passed the verification
    }

    Note that all parameters to zzhpVerifyResponse should be passed not being escaped by SQL quotes. Also the function has the protection against shell injection code.

    Note that function zzhpVerifyResponse doesn't return a boolean value, it returns 0 if everything is OK, and an integer error code otherwise.

More information about these two functions are available inside "zzhpInterface.pl".

4.4. Pure HTML files

It may be possible that your HTML forms are pure HTML files, while the form input is handled by a script (PHP or Perl). However you still need to insert Human Pictcha code inside your pure HTML files. In this case we suggest that you convert your pure HTML file(s) to PHP script(s). This is pretty easy - you just need to rename the file to have the ".php" extension and insert there some PHP code as discussed above wrapped in the <?php and ?> tags.

4.5. Customizing the look

The HTML code being inserted into your forms is defined in the file "zzhpInterface.php", inside the function zzhpCreateRequestHTML, it is wrapped by the HTML comments. You don't have to know PHP in order to modify it, basically it is plain HTML code with some PHP curly braces inside, you just don't have to change anything inside the curly braces. If there are more than one adjacent curly braces, then don't insert any space between them.

5. Security

5.1. Protection from code attacks

ZZEE Human Pictcha was designed with security in mind, it protects itself from various attacks, in particular:

The only thing that you might be concerned about, if you are on a shared web hosting plan, is Mysql database username and password values stored in the "zzhpConfig.php" file. You need to apply the same protection to this part of code as you do for your other scripts which use Mysql connection. In particular, the database credentials can be put inside "httpd.conf" file like discussed in the Mysql Guide to PHP Security. We recommend creating a new Mysql database for Human Pictcha. If your web server runs with you user ID, then set that file's permissions to 0600.

5.2. Defeating Human Pictcha

We implemented lots of things to ensure that Human Pictcha is hard to defeat (being still easy to guess by humans), they include:

We assess the breakability of Human Pictcha with the default settings as pretty low. However, you can tighten the parameters and increase the image distortion very significantly (see file "zzhpConfig.php"). But some reasonable balance should be kept: the harder the image, the harder it will be for a human to guess it. The opposite is true, if the image is being guessed by people with the 100% probability, then the chances are high that it will not be so hard to break by automatic OCR too. We suggest to keep the settings so the people guess the image with the 90% probability, this will make life of OCR pretty hard, and at the same time will allow most people to pass the test from the first attempt. Please see how to measure test pass rate.

6. Miscellaneous

6.1. Fonts

You can add any True Type font into the "fonts" directory, and also need to add it to "zzhpConfig.php" file either. There are lots of free True Type fonts available on the internet, you can use either of them, links are in the References section. However before you place any font to the production environment, you need to evaluate Human Pictcha completion rate in the test environment with this font(s). Different fonts require different size, distortion and other settings. They can be compatible or incompatible with each other.

6.2. Evaluating Human Pictcha completion rate

If you change any settings of Human Pictcha, you need to know how the completion rate changes. You need to configure Human Pictcha to achieve the rate of 90-95%. It shall be neither 100% nor less than 50%. You can use file "/zzhp/test/zzhpTest.php" for performing tests.

To measure the rate in the test environment, first clear the table "zzeeHumanPictcha" by executing this SQL statement:

DELETE FROM zzeeHumanPictcha;

Then complete 50 to 100 tests, and evaluate the results, by running the following SQL queries. For the total number of tests for which the users submitted the verification code:

SELECT COUNT(*) FROM zzeeHumanPictcha WHERE restime;

For the number of passed tests:

SELECT COUNT(*) FROM zzeeHumanPictcha WHERE restime AND answertext = cleartext;

6.3. Demo version

The demo version is needed to make sure that your system is compatible with Human Pictcha and that you can install it before you buy it. It displays one of the two predefined images, each having the word "DEMO" on it. Order your full copy of Human Pictcha here:
http://www.zzee.com/order/?r=hp

7. References